perm filename COMMON.11[COM,LSP] blob
sn#865847 filedate 1988-12-10 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00560 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00070 00002
C00071 00003 ∂04-Jan-88 0929 Common-Lisp-mailer Question about declaration
C00076 00004 ∂04-Jan-88 1424 Common-Lisp-mailer &REST lists
C00078 00005 ∂04-Jan-88 1728 Common-Lisp-mailer &REST lists
C00081 00006 ∂05-Jan-88 0031 Common-Lisp-mailer &REST lists
C00084 00007 ∂05-Jan-88 1225 Common-Lisp-mailer &REST lists
C00086 00008 ∂06-Jan-88 2359 Common-Lisp-mailer TYPEP warp implications
C00095 00009 ∂07-Jan-88 0759 Common-Lisp-mailer the array type mess....
C00098 00010 ∂07-Jan-88 1005 Common-Lisp-mailer &REST lists
C00101 00011 ∂07-Jan-88 2102 Common-Lisp-mailer setf subseq question
C00104 00012 ∂07-Jan-88 2139 Common-Lisp-mailer setf subseq question
C00107 00013 ∂08-Jan-88 1740 Common-Lisp-mailer side-effecting functions ...
C00110 00014 ∂08-Jan-88 2029 Common-Lisp-mailer TYPEP warp implications
C00112 00015 ∂08-Jan-88 2029 Common-Lisp-mailer the array type mess....
C00115 00016 ∂09-Jan-88 1255 Common-Lisp-mailer the array type mess....
C00124 00017 ∂14-Jan-88 2128 Common-Lisp-mailer setf subseq question
C00129 00018 ∂15-Jan-88 1440 Common-Lisp-mailer fill-pointer
C00132 00019 ∂15-Jan-88 1511 Common-Lisp-mailer fill-pointer
C00135 00020 ∂15-Jan-88 1724 Common-Lisp-mailer fill-pointer
C00138 00021 ∂18-Jan-88 1543 Common-Lisp-mailer (simulated) multiprocessor extensions to Common Lisp?
C00141 00022 ∂19-Jan-88 0502 Common-Lisp-mailer Scheme standard?
C00142 00023 ∂20-Jan-88 0007 Common-Lisp-mailer circular structure syntax
C00144 00024 ∂22-Jan-88 1831 Common-Lisp-mailer type declarations of special bindings
C00146 00025 ∂22-Jan-88 2323 Common-Lisp-mailer Type specifiers in THE constructs
C00149 00026 ∂22-Jan-88 2323 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
C00152 00027 ∂23-Jan-88 0125 Common-Lisp-mailer type declarations of special bindings
C00155 00028 ∂23-Jan-88 1212 Common-Lisp-mailer Re: Type specifiers in THE constructs
C00159 00029 ∂24-Jan-88 0618 Common-Lisp-mailer Type specifiers in THE constructs
C00162 00030 ∂25-Jan-88 1408 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
C00167 00031 ∂26-Jan-88 0627 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
C00171 00032 ∂26-Jan-88 1807 Common-Lisp-mailer Re: Type specifiers in THE constructs
C00173 00033 ∂26-Jan-88 1924 Common-Lisp-mailer type declarations of special bindings
C00177 00034 ∂27-Jan-88 0845 Common-Lisp-mailer , and #
C00179 00035 ∂28-Jan-88 0424 Common-Lisp-mailer , and #
C00181 00036 ∂28-Jan-88 0828 Common-Lisp-mailer , and #
C00183 00037 ∂28-Jan-88 1025 Common-Lisp-mailer , and #
C00185 00038 ∂28-Jan-88 1210 Common-Lisp-mailer [king@kestrel.arpa: commonlisp errors]
C00187 00039 ∂31-Jan-88 1442 Common-Lisp-mailer Re: LEAST-POSITIVE-<mumble>-FLOAT
C00192 00040 ∂01-Feb-88 0913 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
C00197 00041 ∂03-Feb-88 1844 Common-Lisp-mailer Issue: EXPORT-IMPORT
C00200 00042 ∂03-Feb-88 1949 Common-Lisp-mailer EXPORT-IMPORT and the other random commands
C00204 00043 ∂05-Feb-88 2052 Common-Lisp-mailer EXPORT-IMPORT and the other random commands
C00208 00044 ∂05-Feb-88 2056 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
C00212 00045 ∂07-Feb-88 0015 Common-Lisp-mailer Re: {Improved version} EXPORT-IMPORT and the other random commands
C00216 00046 ∂07-Feb-88 0404 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
C00223 00047 ∂07-Feb-88 0849 Common-Lisp-mailer REQUEST FOR CHANGE IN DISTRIBUTION
C00225 00048 ∂11-Feb-88 0120 Common-Lisp-mailer Please change my address
C00227 00049 ∂11-Feb-88 1637 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
C00234 00050 ∂12-Feb-88 0813 Common-Lisp-mailer Package Odor
C00238 00051 ∂12-Feb-88 1201 Common-Lisp-mailer defpackage
C00241 00052 ∂12-Feb-88 2220 Common-Lisp-mailer Package Odor
C00246 00053 ∂13-Feb-88 1646 Common-Lisp-mailer Re: {Improved version} EXPORT-IMPORT and the other random commands
C00249 00054 ∂14-Feb-88 2147 Common-Lisp-mailer Package Odor
C00256 00055 ∂15-Feb-88 1521 Common-Lisp-mailer Package odor
C00260 00056 ∂15-Feb-88 2232 Common-Lisp-mailer Creepy Crawlers in the Package system
C00264 00057 ∂18-Feb-88 1208 Common-Lisp-mailer Results of query regarding multiprocessor applications and simulators
C00271 00058 ∂18-Feb-88 1400 Common-Lisp-mailer Heat and Howard Trickey
C00273 00059 ∂19-Feb-88 0952 Common-Lisp-mailer Results of query regarding multiprocessor applications and simulators
C00275 00060 ∂24-Feb-88 1803 Common-Lisp-mailer Heat and Howard Trickey
C00277 00061 ∂25-Feb-88 1439 Common-Lisp-mailer Heat and Howard Trickey
C00280 00062 ∂26-Feb-88 1235 Common-Lisp-mailer package question
C00283 00063 ∂26-Feb-88 1237 Common-Lisp-mailer the KEYWORD package ...
C00286 00064 ∂26-Feb-88 1400 Common-Lisp-mailer the KEYWORD package ...
C00289 00065 ∂26-Feb-88 1445 Common-Lisp-mailer package question
C00294 00066 ∂27-Feb-88 1036 Common-Lisp-mailer Lisp Innards Wanted!
C00299 00067 ∂28-Feb-88 0116 Common-Lisp-mailer package question
C00301 00068 ∂28-Feb-88 0618 Common-Lisp-mailer package question
C00303 00069 ∂29-Feb-88 0408 Common-Lisp-mailer Re: Lisp Innards Wanted!
C00305 00070 ∂29-Feb-88 0634 Common-Lisp-mailer Order of arguments to sequence :TEST functions
C00309 00071 ∂29-Feb-88 0757 Common-Lisp-mailer Order of arguments to sequence :TEST functions
C00312 00072 ∂29-Feb-88 0935 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
C00315 00073 ∂29-Feb-88 1003 Common-Lisp-mailer Re: package question
C00317 00074 ∂29-Feb-88 1025 Common-Lisp-mailer Re: package question
C00319 00075 ∂29-Feb-88 1047 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
C00322 00076 ∂29-Feb-88 1050 Common-Lisp-mailer Re: Order of arguments to sequence :TEST functions
C00324 00077 ∂29-Feb-88 1051 Common-Lisp-mailer Order of arguments to sequence :TEST functions
C00327 00078 ∂29-Feb-88 1056 Common-Lisp-mailer Order of arguments to sequence :TEST functions
C00330 00079 ∂29-Feb-88 1120 Common-Lisp-mailer Re: the KEYWORD package ...
C00334 00080 ∂29-Feb-88 1208 Common-Lisp-mailer Order of arguments to sequence :TEST functions
C00337 00081 ∂29-Feb-88 1359 Common-Lisp-mailer Re: Order of arguments to sequence :TEST functions
C00340 00082 ∂29-Feb-88 1646 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
C00343 00083 ∂29-Feb-88 1853 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
C00345 00084 ∂29-Feb-88 2111 Common-Lisp-mailer the KEYWORD package USEing another package
C00348 00085 ∂01-Mar-88 0807 Common-Lisp-mailer the KEYWORD package USEing another package
C00351 00086 ∂01-Mar-88 0854 Common-Lisp-mailer Re: the KEYWORD package USEing another package
C00354 00087 ∂01-Mar-88 0910 Common-Lisp-mailer Re: the KEYWORD package USEing another package
C00358 00088 ∂01-Mar-88 1409 Common-Lisp-mailer the KEYWORD package USEing another package
C00362 00089 ∂01-Mar-88 2351 Common-Lisp-mailer keywords revisited
C00367 00090 ∂02-Mar-88 1203 Common-Lisp-mailer Request to be added to mailing list...
C00369 00091 ∂06-Mar-88 1211 Common-Lisp-mailer A keyword data type
C00372 00092 ∂08-Mar-88 0831 Common-Lisp-mailer A keyword data type
C00376 00093 ∂08-Mar-88 1142 Common-Lisp-mailer A keyword data type
C00384 00094 ∂09-Mar-88 1313 Common-Lisp-mailer defsys
C00386 00095 ∂09-Mar-88 1843 Common-Lisp-mailer CLOS Consortium
C00390 00096 ∂10-Mar-88 1641 Common-Lisp-mailer Re: A keyword data type
C00393 00097 ∂11-Mar-88 1105 Common-Lisp-mailer &REST lists
C00396 00098 ∂11-Mar-88 1147 Common-Lisp-mailer &REST lists
C00398 00099 ∂11-Mar-88 1306 Common-Lisp-mailer the array type mess....
C00404 00100 ∂11-Mar-88 1344 Common-Lisp-mailer Re: &REST lists
C00409 00101 ∂11-Mar-88 1410 Common-Lisp-mailer &REST lists
C00412 00102 ∂11-Mar-88 1430 Common-Lisp-mailer &REST lists
C00414 00103 ∂11-Mar-88 1434 Common-Lisp-mailer Re: &REST lists
C00419 00104 ∂11-Mar-88 1457 Common-Lisp-mailer &REST lists
C00422 00105 ∂11-Mar-88 1606 Common-Lisp-mailer Re: &REST lists
C00426 00106 ∂11-Mar-88 1638 Common-Lisp-mailer Re: &REST lists
C00430 00107 ∂11-Mar-88 2022 Common-Lisp-mailer the array type mess....
C00437 00108 ∂13-Mar-88 0449 Common-Lisp-mailer &rest lists - correction
C00439 00109 ∂13-Mar-88 0449 Common-Lisp-mailer &rest lists and other things ground through function application
C00442 00110 ∂14-Mar-88 0847 Common-Lisp-mailer New defsys available for public anonymous ftp
C00444 00111 ∂14-Mar-88 2257 Common-Lisp-mailer &Rest Lists
C00449 00112 ∂16-Mar-88 1158 Common-Lisp-mailer &Rest Lists
C00452 00113 ∂16-Mar-88 1349 Common-Lisp-mailer &Rest Lists
C00455 00114 ∂16-Mar-88 1729 Common-Lisp-mailer &Rest Lists
C00458 00115 ∂16-Mar-88 1747 Common-Lisp-mailer &REST args
C00461 00116 ∂16-Mar-88 1754 Common-Lisp-mailer &rest args -- (declarations)
C00463 00117 ∂17-Mar-88 0511 Common-Lisp-mailer &REST args
C00466 00118 ∂18-Mar-88 1444 Common-Lisp-mailer &REST args
C00469 00119 ∂19-Mar-88 0055 Common-Lisp-mailer &REST args
C00471 00120 ∂19-Mar-88 0156 Common-Lisp-mailer &rest lists and other things ground through function application
C00474 00121 ∂19-Mar-88 1153 Common-Lisp-mailer &rest lists and other things ground through function application
C00477 00122 ∂19-Mar-88 1154 Common-Lisp-mailer &REST args
C00479 00123 ∂19-Mar-88 1404 Common-Lisp-mailer &REST args
C00484 00124 ∂19-Mar-88 2304 Common-Lisp-mailer &rest lists should not be copied
C00490 00125 ∂21-Mar-88 0810 Common-Lisp-mailer CLOS Status
C00492 00126 ∂23-Mar-88 1313 Common-Lisp-mailer &Rest Lists
C00499 00127 ∂23-Mar-88 1731 Common-Lisp-mailer &Rest Lists
C00508 00128 ∂23-Mar-88 1830 Common-Lisp-mailer &Rest Lists
C00517 00129 ∂24-Mar-88 0930 Common-Lisp-mailer &REST Lists
C00522 00130 ∂24-Mar-88 0952 Common-Lisp-mailer &REST Lists
C00527 00131 ∂24-Mar-88 2246 Common-Lisp-mailer &Rest Lists
C00540 00132 ∂24-Mar-88 2333 Common-Lisp-mailer &Rest Lists
C00550 00133 ∂29-Mar-88 1951 Common-Lisp-mailer Re: &REST lists
C00555 00134 ∂29-Mar-88 2340 Common-Lisp-mailer &Rest Lists
C00564 00135 ∂30-Mar-88 1055 Common-Lisp-mailer &Rest Lists
C00571 00136 ∂30-Mar-88 1140 Common-Lisp-mailer &Rest Lists
C00586 00137 ∂01-Apr-88 2328 Common-Lisp-mailer &Rest Lists
C00596 00138 ∂02-Apr-88 0959 Common-Lisp-mailer Re: &Rest Lists
C00599 00139 ∂04-Apr-88 0649 Common-Lisp-mailer RE: &Rest Lists
C00601 00140 ∂04-Apr-88 0724 Common-Lisp-mailer &rest replacement/addition
C00604 00141 ∂04-Apr-88 0810 Common-Lisp-mailer &rest replacement/addition
C00607 00142 ∂04-Apr-88 0932 Common-Lisp-mailer Re: &rest replacement/addition
C00610 00143 ∂04-Apr-88 1002 Common-Lisp-mailer Re: &rest replacement/addition
C00615 00144 ∂04-Apr-88 1041 Common-Lisp-mailer Re: &rest replacement/addition
C00620 00145 ∂05-Apr-88 0550 Common-Lisp-mailer Re: &rest replacement/addition
C00623 00146 ∂05-Apr-88 1437 Common-Lisp-mailer
C00625 00147 ∂05-Apr-88 2257 Common-Lisp-mailer &Rest args and Optimizations
C00629 00148 ∂05-Apr-88 2305 Common-Lisp-mailer &rest replacement/addition
C00635 00149 ∂06-Apr-88 0926 Common-Lisp-mailer
C00636 00150 ∂06-Apr-88 0956 Common-Lisp-mailer &rest replacement/addition
C00640 00151 ∂06-Apr-88 1136 Common-Lisp-mailer
C00644 00152 ∂06-Apr-88 1225 Common-Lisp-mailer Re:
C00645 00153 ∂06-Apr-88 1341 Common-Lisp-mailer Problems with setf and structures
C00648 00154 ∂07-Apr-88 1045 Common-Lisp-mailer Re: Problems with SETF and structures
C00654 00155 ∂08-Apr-88 0001 Common-Lisp-mailer &Rest Lists
C00656 00156 ∂08-Apr-88 0115 Common-Lisp-mailer &rest [discussion] replacement/addition
C00665 00157 ∂08-Apr-88 0335 Common-Lisp-mailer
C00668 00158 ∂08-Apr-88 0335 Common-Lisp-mailer &rest replacement/addition
C00671 00159 ∂08-Apr-88 1018 Common-Lisp-mailer LetRec?
C00672 00160 ∂08-Apr-88 1204 Common-Lisp-mailer LetRec?
C00674 00161 ∂08-Apr-88 1217 Common-Lisp-mailer Re: LetRec?
C00676 00162 ∂08-Apr-88 1243 Common-Lisp-mailer Re: LetRec?
C00679 00163 ∂08-Apr-88 1258 Common-Lisp-mailer LetRec
C00681 00164 ∂08-Apr-88 1357 Common-Lisp-mailer Re: LetRec?
C00684 00165 ∂08-Apr-88 1412 Common-Lisp-mailer &rest [discussion] replacement/addition
C00692 00166 ∂08-Apr-88 1503 Common-Lisp-mailer Re: LetRec?
C00696 00167 ∂08-Apr-88 1531 Common-Lisp-mailer &rest [discussion] replacement/addition
C00699 00168 ∂08-Apr-88 1541 Common-Lisp-mailer LetRec
C00702 00169 ∂08-Apr-88 1601 Common-Lisp-mailer LetRec
C00705 00170 ∂08-Apr-88 1617 Common-Lisp-mailer LetRec
C00707 00171 ∂08-Apr-88 1724 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
C00709 00172 ∂08-Apr-88 1915 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
C00712 00173 ∂09-Apr-88 0528 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
C00716 00174 ∂09-Apr-88 2212 Common-Lisp-mailer LetRec
C00719 00175 ∂10-Apr-88 0702 Common-Lisp-mailer &rest arguments
C00722 00176 ∂11-Apr-88 1124 Common-Lisp-mailer LetRec
C00724 00177 ∂11-Apr-88 1130 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
C00731 00178 ∂11-Apr-88 1341 Common-Lisp-mailer LetRec
C00737 00179 ∂11-Apr-88 1434 Common-Lisp-mailer Question on terminology
C00740 00180 ∂12-Apr-88 0654 Common-Lisp-mailer &rest [discussion] replacement/addition
C00745 00181 ∂13-Apr-88 1100 Common-Lisp-mailer Re: &rest [discussion] replacement/addition
C00750 00182 ∂14-Apr-88 0053 Common-Lisp-mailer LetRec
C00755 00183 ∂14-Apr-88 2016 Common-Lisp-mailer Reader references
C00757 00184 ∂14-Apr-88 2315 Common-Lisp-mailer &rest [discussion] replacement/addition
C00760 00185 ∂21-Apr-88 1030 Common-Lisp-mailer Lisp & Functional Programming 88 (LONG)
C00781 00186 ∂26-Apr-88 1619 Common-Lisp-mailer miscellaneous questions about declarations and type specfiers
C00783 00187 ∂26-Apr-88 1840 Common-Lisp-mailer Re: miscellaneous questions about declarations and type specfiers
C00785 00188 ∂26-Apr-88 2114 Common-Lisp-mailer miscellaneous questions about declarations and type specfiers
C00789 00189 ∂05-May-88 0713 Common-Lisp-mailer Constant Functions
C00793 00190 ∂05-May-88 1740 Common-Lisp-mailer Industrial-strength Lisp?
C00800 00191 ∂05-May-88 1916 Common-Lisp-mailer Constant Functions
C00804 00192 ∂06-May-88 1119 Common-Lisp-mailer constant-function
C00806 00193 ∂06-May-88 1434 Common-Lisp-mailer Constant Functions
C00813 00194 ∂07-May-88 0456 Common-Lisp-mailer Constant Functions
C00817 00195 ∂07-May-88 1000 Common-Lisp-mailer Constant Functions
C00822 00196 ∂07-May-88 1059 Common-Lisp-mailer Re: Constant Functions
C00826 00197 ∂07-May-88 2109 Common-Lisp-mailer Constant Functions
C00832 00198 ∂09-May-88 0926 Common-Lisp-mailer Re: Constant Functions
C00835 00199 ∂09-May-88 0926 Common-Lisp-mailer [not about] Constant Functions
C00839 00200 ∂09-May-88 1416 Common-Lisp-mailer [not about] Constant Functions
C00842 00201 ∂09-May-88 1420 Common-Lisp-mailer Constant Functions
C00846 00202 ∂09-May-88 1827 Common-Lisp-mailer [not about] Constant Functions
C00849 00203 ∂09-May-88 2216 Common-Lisp-mailer Constant-Function
C00855 00204 ∂09-May-88 2234 Common-Lisp-mailer [not about] Constant Functions
C00857 00205 ∂09-May-88 2316 Common-Lisp-mailer Features
C00861 00206 ∂10-May-88 0054 Common-Lisp-mailer Features
C00866 00207 ∂10-May-88 1333 Common-Lisp-mailer [Reducible declaration? and] Constant-Function
C00871 00208 ∂10-May-88 1408 Common-Lisp-mailer Features
C00875 00209 ∂10-May-88 1419 Common-Lisp-mailer Constant-Function
C00883 00210 ∂10-May-88 1926 Common-Lisp-mailer Constant-Function
C00886 00211 ∂11-May-88 0814 Common-Lisp-mailer Constant-Function
C00890 00212 ∂12-May-88 0013 Common-Lisp-mailer Constant-Function
C00895 00213 ∂12-May-88 0037 Common-Lisp-mailer Constant-Function
C00904 00214 ∂12-May-88 0038 Common-Lisp-mailer Constant-Function
C00910 00215 ∂12-May-88 2147 Common-Lisp-mailer Constant-Function
C00917 00216 ∂12-May-88 2159 Common-Lisp-mailer Constant-Function, and integration-level
C00921 00217 ∂12-May-88 2220 Common-Lisp-mailer visible hash tables
C00924 00218 ∂13-May-88 0050 Common-Lisp-mailer visible hash tables
C00926 00219 ∂13-May-88 0051 Common-Lisp-mailer visible hash tables
C00928 00220 ∂13-May-88 0218 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00935 00221 ∂13-May-88 0840 Common-Lisp-mailer visible hash tables
C00938 00222 ∂13-May-88 0841 Common-Lisp-mailer Re: SIDE-EFFECT-FREE/STATELESS Functions
C00942 00223 ∂13-May-88 0932 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00948 00224 ∂13-May-88 0933 Common-Lisp-mailer visible hash tables
C00950 00225 ∂13-May-88 1125 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00953 00226 ∂13-May-88 1238 Common-Lisp-mailer Re: Constant-Function, and integration-level
C00957 00227 ∂13-May-88 1248 Common-Lisp-mailer Re: Constant-Function
C00961 00228 ∂13-May-88 1453 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00966 00229 ∂13-May-88 1533 Common-Lisp-mailer Constant-Function, and integration-level
C00969 00230 ∂13-May-88 1801 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00975 00231 ∂13-May-88 2033 Common-Lisp-mailer replies to hash table comments
C00979 00232 ∂14-May-88 0015 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00982 00233 ∂16-May-88 1603 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C00988 00234 ∂16-May-88 1619 Common-Lisp-mailer Re: Constant-Function, and integration-level
C00991 00235 ∂16-May-88 1703 Common-Lisp-mailer Re: replies to hash table comments
C00993 00236 ∂16-May-88 1802 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C01000 00237 ∂16-May-88 1834 Common-Lisp-mailer #H syntax
C01003 00238 ∂16-May-88 1941 Common-Lisp-mailer #H syntax
C01006 00239 ∂16-May-88 2357 Common-Lisp-mailer visible hash tables
C01010 00240 ∂17-May-88 0008 Common-Lisp-mailer Re: visible hash tables
C01012 00241 ∂17-May-88 0101 Common-Lisp-mailer Re: visible hash tables
C01017 00242 ∂17-May-88 0133 Common-Lisp-mailer Re: visible hash tables
C01022 00243 ∂17-May-88 0745 Common-Lisp-mailer visible hash tables
C01029 00244 ∂17-May-88 0858 Common-Lisp-mailer visible hash tables
C01032 00245 ∂17-May-88 1217 Common-Lisp-mailer RE: Visible Hash-Tables
C01035 00246 ∂17-May-88 1336 Common-Lisp-mailer (aside about) visible hash tables
C01042 00247 ∂17-May-88 1514 Common-Lisp-mailer RE: Visible Hash-Tables
C01045 00248 ∂17-May-88 1628 Common-Lisp-mailer [portable pathname formats] visible hash tables
C01048 00249 ∂17-May-88 2300 Common-Lisp-mailer visible hash tables
C01051 00250 ∂18-May-88 0000 Common-Lisp-mailer Visible Hash-Tables
C01054 00251 ∂18-May-88 1112 Common-Lisp-mailer request to change my mailing address
C01056 00252 ∂18-May-88 1853 Common-Lisp-mailer visible hash table nit
C01058 00253 ∂18-May-88 1858 Common-Lisp-mailer Features
C01060 00254 ∂18-May-88 2118 Common-Lisp-mailer Re: visible hash table nit
C01062 00255 ∂19-May-88 0043 Common-Lisp-mailer Features
C01064 00256 ∂19-May-88 0738 Common-Lisp-mailer Features
C01067 00257 ∂19-May-88 0813 Common-Lisp-mailer Readable Hash-Tables
C01070 00258 ∂19-May-88 1216 Common-Lisp-mailer Re: Readable Hash-Tables
C01073 00259 ∂19-May-88 1829 Common-Lisp-mailer [portable pathname formats] visible hash tables
C01077 00260 ∂20-May-88 2240 Common-Lisp-mailer STATELESS/SIDE-EFFECT-FREE Functions
C01085 00261 ∂24-May-88 1408 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C01089 00262 ∂24-May-88 1431 Common-Lisp-mailer replies to hash table comments
C01095 00263 ∂24-May-88 1524 Common-Lisp-mailer replies to hash table comments
C01098 00264 ∂24-May-88 1831 Common-Lisp-mailer replies to hash table comments
C01103 00265 ∂28-May-88 2031 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
C01107 00266 ∂31-May-88 1252 Common-Lisp-mailer constant folding/smashing
C01117 00267 ∂01-Jun-88 1237 Common-Lisp-mailer Re: constant folding/smashing
C01126 00268 ∂01-Jun-88 1438 Common-Lisp-mailer Re: constant folding/smashing
C01135 00269 ∂06-Jun-88 1230 Common-Lisp-mailer
C01136 00270 ∂07-Jun-88 0058 Common-Lisp-mailer
C01138 00271 ∂07-Jun-88 0722 Common-Lisp-mailer Re: little question
C01141 00272 ∂07-Jun-88 1023 Common-Lisp-mailer Re: constant folding/smashing
C01144 00273 ∂07-Jun-88 1326 Common-Lisp-mailer Re: constant folding/smashing
C01150 00274 ∂07-Jun-88 1509 Common-Lisp-mailer Re: constant folding/smashing
C01159 00275 ∂08-Jun-88 0251 Common-Lisp-mailer
C01161 00276 ∂08-Jun-88 1043 Common-Lisp-mailer Re: constant folding/smashing
C01165 00277 ∂08-Jun-88 1257 Common-Lisp-mailer Re: constant folding/smashing
C01168 00278 ∂08-Jun-88 1301 Common-Lisp-mailer Call for publishable code!
C01172 00279 ∂08-Jun-88 1349 Common-Lisp-mailer Re: constant folding/smashing
C01181 00280 ∂08-Jun-88 1352 Common-Lisp-mailer Re: Call for publishable code!
C01183 00281 ∂08-Jun-88 1408 Common-Lisp-mailer Re: constant folding/smashing
C01186 00282 ∂09-Jun-88 0203 Common-Lisp-mailer CLOS questions, PCL version
C01190 00283 ∂09-Jun-88 1429 Common-Lisp-mailer Re: constant folding/smashing
C01196 00284 ∂09-Jun-88 1439 Common-Lisp-mailer Remove from Distribution
C01198 00285 ∂09-Jun-88 1510 Common-Lisp-mailer constant folding/smashing
C01207 00286 ∂10-Jun-88 0457 Common-Lisp-mailer
C01208 00287 ∂10-Jun-88 0806 Common-Lisp-mailer Re: constant folding/smashing
C01216 00288 ∂10-Jun-88 1129 Common-Lisp-mailer Re: constant folding/smashing
C01223 00289 ∂10-Jun-88 1225 Common-Lisp-mailer Re: constant folding/smashing
C01226 00290 ∂10-Jun-88 1329 Common-Lisp-mailer Re: constant folding/smashing
C01234 00291 ∂10-Jun-88 1639 Common-Lisp-mailer constant folding/smashing
C01236 00292 ∂10-Jun-88 1834 Common-Lisp-mailer EQUAL
C01241 00293 ∂10-Jun-88 2037 Common-Lisp-mailer constant folding/smashing
C01246 00294 ∂10-Jun-88 2316 Common-Lisp-mailer constant folding/smashing
C01250 00295 ∂11-Jun-88 1024 RPG
C01253 00296 ∂11-Jun-88 1738 Common-Lisp-mailer EQUAL
C01256 00297 ∂11-Jun-88 1755 Common-Lisp-mailer constant folding/smashing
C01259 00298 ∂11-Jun-88 1836 Common-Lisp-mailer constant folding/smashing (constant hash tables)
C01262 00299 ∂12-Jun-88 2212 Common-Lisp-mailer Backquote Constants
C01268 00300 ∂12-Jun-88 2311 Common-Lisp-mailer EQUAL
C01274 00301 ∂12-Jun-88 2332 Common-Lisp-mailer constant folding/smashing
C01279 00302 ∂13-Jun-88 1004 Common-Lisp-mailer EQUAL
C01284 00303 ∂13-Jun-88 1152 Common-Lisp-mailer EQUAL
C01290 00304 ∂13-Jun-88 1248 Common-Lisp-mailer constant folding/smashing
C01292 00305 ∂13-Jun-88 1439 Common-Lisp-mailer Re: constant folding/smashing
C01294 00306 ∂13-Jun-88 1551 Common-Lisp-mailer Re: constant folding/smashing
C01298 00307 ∂14-Jun-88 1133 Common-Lisp-mailer (macro . atom)
C01304 00308 ∂15-Jun-88 0014 Common-Lisp-mailer smashed constants
C01307 00309 ∂15-Jun-88 0014 Common-Lisp-mailer Constant Smashing
C01316 00310 ∂15-Jun-88 0139 Common-Lisp-mailer smashed constants
C01319 00311 ∂15-Jun-88 0817 Common-Lisp-mailer Re: Constant Smashing
C01328 00312 ∂15-Jun-88 1624 Common-Lisp-mailer Constant Smashing
C01330 00313 ∂15-Jun-88 2004 Common-Lisp-mailer copy
C01331 00314 ∂15-Jun-88 2056 Common-Lisp-mailer copy
C01338 00315 ∂16-Jun-88 1009 Common-Lisp-mailer L&FP Registration Forms
C01342 00316 ∂16-Jun-88 1016 Common-Lisp-mailer More on L&FP Registration Forms
C01344 00317 ∂17-Jun-88 1017 Common-Lisp-mailer Re: constant folding/smashing
C01346 00318 ∂19-Jun-88 1717 Common-Lisp-mailer #, read macro
C01348 00319 ∂19-Jun-88 2355 Common-Lisp-mailer #, read macro
C01350 00320 ∂20-Jun-88 1006 Common-Lisp-mailer #, read macro
C01354 00321 ∂20-Jun-88 1237 CL-Compiler-mailer Re: #, read macro
C01357 00322 ∂23-Jun-88 1144 Common-Lisp-mailer constant smashing
C01370 00323 ∂24-Jun-88 1552 Common-Lisp-mailer EQUAL
C01376 00324 ∂24-Jun-88 1614 Common-Lisp-mailer constant folding/smashing
C01384 00325 ∂24-Jun-88 1647 Common-Lisp-mailer EQUAL
C01388 00326 ∂24-Jun-88 1709 Common-Lisp-mailer #.
C01393 00327 ∂24-Jun-88 1819 Common-Lisp-mailer Re: #.
C01395 00328 ∂25-Jun-88 1126 Common-Lisp-mailer Source code analysis tools
C01398 00329 ∂27-Jun-88 1138 Common-Lisp-mailer Issue: STACK-LET (Version 1)
C01406 00330 ∂27-Jun-88 1242 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
C01408 00331 ∂27-Jun-88 1306 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
C01414 00332 ∂27-Jun-88 1338 Common-Lisp-mailer Issue: STACK-LET (Version 1)
C01417 00333 ∂27-Jun-88 1547 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
C01420 00334 ∂28-Jun-88 1150 Common-Lisp-mailer please subscribe this worthless person to the mail list...
C01421 00335 ∂28-Jun-88 1804 Common-Lisp-mailer #.
C01423 00336 ∂28-Jun-88 2239 Common-Lisp-mailer Issue: STACK-LET (Version 1)
C01426 00337 ∂30-Jun-88 0803 Common-Lisp-mailer EQUAL
C01429 00338 ∂30-Jun-88 0804 Common-Lisp-mailer [Re: EQUAL]
C01437 00339 ∂30-Jun-88 1241 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01453 00340 ∂30-Jun-88 1340 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01461 00341 ∂30-Jun-88 1438 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01467 00342 ∂30-Jun-88 2256 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
C01470 00343 ∂01-Jul-88 1217 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01473 00344 ∂02-Jul-88 1146 Common-Lisp-mailer dynamic extent lisp objects
C01476 00345 ∂03-Jul-88 0956 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01481 00346 ∂03-Jul-88 1510 Common-Lisp-mailer Re: dynamic extent lisp objects
C01484 00347 ∂03-Jul-88 2356 Common-Lisp-mailer What have hashing and equality to do with each other?
C01486 00348 ∂05-Jul-88 1749 Common-Lisp-mailer re: EQUAL, and hash tables, and value/object distinctions
C01492 00349 ∂06-Jul-88 1344 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01498 00350 ∂06-Jul-88 1612 Common-Lisp-mailer [Re: EQUAL]
C01502 00351 ∂08-Jul-88 1316 Common-Lisp-mailer
C01504 00352 ∂11-Jul-88 1111 CL-Object-Oriented-Programming-mailer CLOS Workshop
C01508 00353 ∂12-Jul-88 0942 Common-Lisp-mailer L&FP Registration -- FINAL CALL
C01513 00354 ∂15-Jul-88 1302 Common-Lisp-mailer overloading defstruct accessors
C01516 00355 ∂15-Jul-88 1341 Common-Lisp-mailer overloading defstruct accessors
C01519 00356 ∂15-Jul-88 1342 Common-Lisp-mailer overloading defstruct accessors
C01524 00357 ∂15-Jul-88 2001 Common-Lisp-mailer (Not Necessarily Common) LISP Implementation
C01528 00358 ∂16-Jul-88 1818 Common-Lisp-mailer Franz Inc. makes available Allegro CL/GNU Emacs Interface
C01537 00359 ∂18-Jul-88 1555 Common-Lisp-mailer (Not Necessarily Common) LISP Implementation
C01540 00360 ∂18-Jul-88 2049 Common-Lisp-mailer arithmeticprecision
C01542 00361 ∂19-Jul-88 0102 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01550 00362 ∂19-Jul-88 0102 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01557 00363 ∂19-Jul-88 0826 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01562 00364 ∂19-Jul-88 1256 Common-Lisp-mailer Question about readtable null arguments
C01568 00365 ∂19-Jul-88 1331 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01573 00366 ∂19-Jul-88 1438 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01579 00367 ∂20-Jul-88 0107 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
C01581 00368 ∂20-Jul-88 0143 Common-Lisp-mailer Contagion on numerical comparisons
C01587 00369 ∂20-Jul-88 0853 Common-Lisp-mailer L&FP Transportation
C01590 00370 ∂20-Jul-88 1048 Common-Lisp-mailer hash tables
C01593 00371 ∂21-Jul-88 0933 Common-Lisp-mailer hash tables and GC
C01597 00372 ∂21-Jul-88 1138 Common-Lisp-mailer Re: hash tables and GC
C01600 00373 ∂22-Jul-88 0447 Common-Lisp-mailer hash tables and GC
C01604 00374 ∂22-Jul-88 0732 Common-Lisp-mailer hash tables and GC
C01606 00375 ∂22-Jul-88 0956 RPG Address Change
C01609 00376 ∂22-Jul-88 1001 Common-Lisp-mailer hash tables and GC
C01613 00377 ∂22-Jul-88 1134 Common-Lisp-mailer Re: hash tables and GC
C01617 00378 ∂22-Jul-88 1135 Common-Lisp-mailer Re: hash tables and GC
C01622 00379 ∂22-Jul-88 1150 Common-Lisp-mailer hash tables and GC
C01627 00380 ∂22-Jul-88 1221 Common-Lisp-mailer Re: hash tables and GC
C01631 00381 ∂22-Jul-88 1232 Common-Lisp-mailer hash tables and GC
C01634 00382 ∂22-Jul-88 1717 Common-Lisp-mailer Re: hash tables and GC
C01638 00383 ∂03-Aug-88 1644 Common-Lisp-mailer Removal request
C01639 00384 ∂04-Aug-88 0056 Common-Lisp-mailer Hash Tables and GC
C01643 00385 ∂04-Aug-88 1455 Common-Lisp-mailer [Re: Hash Tables and GC]
C01647 00386 ∂06-Aug-88 0244 Common-Lisp-mailer [Re: Hashables and GC]
C01655 00387 ∂09-Aug-88 0943 Common-Lisp-mailer request
C01656 00388 ∂11-Aug-88 1444 X3J13-mailer CLOS workshop
C01661 00389 ∂11-Aug-88 1607 X3J13-mailer CLOS workshop
C01666 00390 ∂16-Aug-88 1239 Common-Lisp-mailer A Quick Note on the Last L&FP Conference
C01668 00391 ∂21-Aug-88 0047 Common-Lisp-mailer negative values for the :COUNT keyord argument
C01671 00392 ∂21-Aug-88 1238 Common-Lisp-mailer Re: negative values for the :COUNT keyord argument
C01674 00393 ∂22-Aug-88 1034 Common-Lisp-mailer
C01676 00394 ∂24-Aug-88 1214 Common-Lisp-mailer
C01678 00395 ∂24-Aug-88 1215 Common-Lisp-mailer
C01680 00396 ∂25-Aug-88 1356 Common-Lisp-mailer READ and "illegal" characters
C01683 00397 ∂25-Aug-88 1715 Common-Lisp-mailer negative values for the :COUNT keyord argument
C01685 00398 ∂25-Aug-88 2242 Common-Lisp-mailer proposals regarding :COUNT keyword
C01687 00399 ∂26-Aug-88 0759 Common-Lisp-mailer negative values for the :COUNT keyord argument
C01690 00400 ∂27-Aug-88 1917 Common-Lisp-mailer Standard total ordering
C01693 00401 ∂27-Aug-88 1917 Common-Lisp-mailer Re: hash tables and GC
C01708 00402 ∂29-Aug-88 0908 Common-Lisp-mailer Re: hash tables and GC
C01712 00403 ∂29-Aug-88 2104 Common-Lisp-mailer Re: hash tables and GC
C01715 00404 ∂29-Aug-88 2236 Common-Lisp-mailer Re: hash tables and GC
C01718 00405 ∂30-Aug-88 0952 Common-Lisp-mailer READ and "illegal" characters
C01723 00406 ∂30-Aug-88 1636 Common-Lisp-mailer RE: Read and "illegal" characters
C01725 00407 ∂30-Aug-88 2214 Common-Lisp-mailer RE: Read and "illegal" characters
C01730 00408 ∂31-Aug-88 1806 Common-Lisp-mailer Re: hash tables and GC
C01735 00409 ∂31-Aug-88 1849 Common-Lisp-mailer Re: hash tables and GC
C01741 00410 ∂31-Aug-88 1950 Common-Lisp-mailer Re: hash tables and GC
C01746 00411 ∂01-Sep-88 0830 Common-Lisp-mailer Re: hash tables and GC
C01749 00412 ∂01-Sep-88 0924 Common-Lisp-mailer Re: hash tables and GC
C01752 00413 ∂01-Sep-88 1210 Common-Lisp-mailer Re: hash tables and GC
C01755 00414 ∂01-Sep-88 2339 Common-Lisp-mailer hash tables and GC
C01760 00415 ∂03-Sep-88 1147 Common-Lisp-mailer Re: hash tables and GC
C01763 00416 ∂04-Sep-88 1229 Common-Lisp-mailer Re: hash tables and GC
C01766 00417 ∂04-Sep-88 1319 Common-Lisp-mailer Re: hash tables and GC
C01772 00418 ∂06-Sep-88 1808 Common-Lisp-mailer Hash Tables and GC
C01776 00419 ∂06-Sep-88 1953 Common-Lisp-mailer Re: Hash Tables and GC
C01778 00420 ∂07-Sep-88 0515 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
C01780 00421 ∂07-Sep-88 0913 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
C01784 00422 ∂07-Sep-88 1012 Common-Lisp-mailer Re: Hash Tables and GC
C01790 00423 ∂07-Sep-88 1055 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
C01794 00424 ∂07-Sep-88 1125 Common-Lisp-mailer Re: Hash Tables and GC
C01798 00425 ∂07-Sep-88 1130 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
C01801 00426 ∂07-Sep-88 1159 Common-Lisp-mailer Re: Hash Tables and GC
C01806 00427 ∂07-Sep-88 1222 Common-Lisp-mailer Re: Hash Tables and GC
C01808 00428 ∂07-Sep-88 1252 Common-Lisp-mailer Re: Hash Tables and GC
C01811 00429 ∂07-Sep-88 1254 Common-Lisp-mailer Re: Hash Tables and GC
C01814 00430 ∂07-Sep-88 1305 Common-Lisp-mailer Re: Hash Tables and GC
C01820 00431 ∂07-Sep-88 1306 Common-Lisp-mailer Re: Hash Tables and GC
C01823 00432 ∂07-Sep-88 1310 Common-Lisp-mailer weak pointers vs temporary hash tables
C01826 00433 ∂07-Sep-88 1323 Common-Lisp-mailer Re: Hash Tables and GC
C01830 00434 ∂07-Sep-88 1401 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
C01835 00435 ∂07-Sep-88 1411 Common-Lisp-mailer weak pointers vs temporary hash tables
C01840 00436 ∂08-Sep-88 0542 Common-Lisp-mailer Comparing functions
C01842 00437 ∂08-Sep-88 0801 Common-Lisp-mailer Re: Comparing functions
C01845 00438 ∂09-Sep-88 2044 Common-Lisp-mailer Comparing functions
C01848 00439 ∂11-Sep-88 1007 Common-Lisp-mailer Re: Comparing functions
C01851 00440 ∂11-Sep-88 1014 Common-Lisp-mailer Re: Hash Tables and GC
C01855 00441 ∂12-Sep-88 0522 Common-Lisp-mailer Comparing functions
C01856 00442 ∂12-Sep-88 0522 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01858 00443 ∂12-Sep-88 0807 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01862 00444 ∂12-Sep-88 1146 Common-Lisp-mailer Hash Tables and GC
C01873 00445 ∂12-Sep-88 1248 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01877 00446 ∂12-Sep-88 1249 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01880 00447 ∂12-Sep-88 1347 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01883 00448 ∂12-Sep-88 1556 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01887 00449 ∂13-Sep-88 0623 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
C01888 00450 ∂14-Sep-88 1404 Common-Lisp-mailer Profiling lisp
C01890 00451 ∂14-Sep-88 1753 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
C01896 00452 ∂14-Sep-88 1853 Common-Lisp-mailer Hash Tables and GC
C01900 00453 ∂15-Sep-88 0909 Common-Lisp-mailer (eq #'eq #'eq)
C01902 00454 ∂15-Sep-88 1040 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
C01908 00455 ∂15-Sep-88 1112 Common-Lisp-mailer Profiling lisp
C01910 00456 ∂15-Sep-88 1238 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
C01914 00457 ∂15-Sep-88 1823 Common-Lisp-mailer Testing for #'eqness
C01916 00458 ∂16-Sep-88 0513 Common-Lisp-mailer EQness of functions
C01918 00459 ∂16-Sep-88 0551 Common-Lisp-mailer Re: (eq #'eq #'eq)
C01922 00460 ∂16-Sep-88 0939 Common-Lisp-mailer Re: EQness of functions
C01927 00461 ∂16-Sep-88 1324 Common-Lisp-mailer Common Lisp: The Reference
C01929 00462 ∂16-Sep-88 1449 Common-Lisp-mailer (eq #'eq #'eq) (reply to Jeff Dalton)
C01932 00463 ∂17-Sep-88 0856 Common-Lisp-mailer Re: (eq #'eq #'eq) (reply to Jeff Dalton)
C01937 00464 ∂19-Sep-88 0626 Common-Lisp-mailer Multiple copies of functions
C01941 00465 ∂19-Sep-88 1013 Common-Lisp-mailer Re: Multiple copies of functions
C01949 00466 ∂20-Sep-88 0202 Common-Lisp-mailer Re: Multiple copies of functions
C01953 00467 ∂20-Sep-88 0841 Common-Lisp-mailer Re: Multiple copies of functions
C01961 00468 ∂20-Sep-88 1505 Common-Lisp-mailer Re: Multiple copies of functions
C01969 00469 ∂21-Sep-88 0046 Common-Lisp-mailer (eq #'eq #'eq)
C01972 00470 ∂21-Sep-88 1731 Common-Lisp-mailer KCL (or AKCL) on the Sequent?
C01974 00471 ∂22-Sep-88 1401 Common-Lisp-mailer (eq #'f #'f) and :TEMPORARY hash tables
C01979 00472 ∂22-Sep-88 1558 Common-Lisp-mailer :TEMPORARY hash tables weak pointers
C01989 00473 ∂23-Sep-88 0455 Common-Lisp-mailer
C01992 00474 ∂23-Sep-88 0655 Common-Lisp-mailer (eq #'eq #'eq)
C01994 00475 ∂23-Sep-88 0709 Common-Lisp-mailer Re: (eq #'f #'f) and :TEMPORARY hash tables
C01996 00476 ∂23-Sep-88 1006 Common-Lisp-mailer Re: Hash tables and GC
C01998 00477 ∂23-Sep-88 1039 Common-Lisp-mailer (eq #'f #'f) and :TEMPORARY hash tables
C02000 00478 ∂26-Sep-88 1022 Common-Lisp-mailer I'd like to be removed from the common lisp mailing list
C02001 00479 ∂26-Sep-88 1030 Common-Lisp-mailer
C02003 00480 ∂26-Sep-88 1043 Common-Lisp-mailer Re: (eq #'f #'f) and :TEMPORARY hash tables
C02007 00481 ∂26-Sep-88 1206 Common-Lisp-mailer Seeking Linear Algebra and Optimization code.
C02010 00482 ∂26-Sep-88 1237 Common-Lisp-mailer COMPILER-LET
C02014 00483 ∂26-Sep-88 1413 Common-Lisp-mailer COMPILER-LET
C02018 00484 ∂26-Sep-88 1502 Common-Lisp-mailer Re: COMPILER-LET
C02021 00485 ∂27-Sep-88 1030 CL-Compiler-mailer Re: COMPILER-LET
C02024 00486 ∂27-Sep-88 1039 CL-Compiler-mailer Re: COMPILER-LET
C02027 00487 ∂27-Sep-88 1221 CL-Compiler-mailer Re: COMPILER-LET
C02031 00488 ∂27-Sep-88 1307 CL-Compiler-mailer Re: COMPILER-LET
C02036 00489 ∂30-Sep-88 0933 Common-Lisp-mailer Results on Lisp Profilers
C02041 00490 ∂01-Oct-88 1449 Common-Lisp-mailer Issue: DOTTED-MACRO-FORMS (Version 2)
C02048 00491 ∂02-Oct-88 1909 Common-Lisp-mailer Issue: DOTTED-MACRO-FORMS (Version 2)
C02051 00492 ∂03-Oct-88 1250 Common-Lisp-mailer [Re: Issue: DOTTED-MACRO-FORMS (Version 2)]
C02056 00493 ∂05-Oct-88 1107 Common-Lisp-mailer Hash Tables vs. Alists
C02059 00494 ∂05-Oct-88 1156 Common-Lisp-mailer Hash Tables vs. Alists
C02062 00495 ∂05-Oct-88 1203 Common-Lisp-mailer Hash Tables vs. Alists
C02066 00496 ∂05-Oct-88 1409 Common-Lisp-mailer Re: Hash Tables vs. Alists
C02069 00497 ∂08-Oct-88 0740 Common-Lisp-mailer 1989 conference on Lisp and History of Lisp -- advance notice
C02072 00498 ∂10-Oct-88 0944 Common-Lisp-mailer Re: Common Lisp: The Reference
C02075 00499 ∂13-Oct-88 1530 Common-Lisp-mailer
C02076 00500 ∂13-Oct-88 1806 Common-Lisp-mailer
C02077 00501 ∂13-Oct-88 1909 Common-Lisp-mailer
C02078 00502 ∂19-Oct-88 0754 Common-Lisp-mailer Program Call Structure
C02082 00503 ∂19-Oct-88 1427 Common-Lisp-mailer Re: Program Call Structure
C02085 00504 ∂21-Oct-88 1343 Common-Lisp-mailer CL for Connection Machine?
C02087 00505 ∂21-Oct-88 2123 Common-Lisp-mailer Re: Program Call Structure
C02091 00506 ∂24-Oct-88 1226 Common-Lisp-mailer common lisp ops5
C02093 00507 ∂24-Oct-88 1439 Common-Lisp-mailer Public Domain OPS5 available.
C02095 00508 ∂25-Oct-88 0652 Common-Lisp-mailer common lisp ops5
C02097 00509 ∂25-Oct-88 1840 Common-Lisp-mailer Re: Program Call Structure
C02101 00510 ∂03-Nov-88 1751 Common-Lisp-mailer LALR parser generator
C02102 00511 ∂04-Nov-88 0143 Common-Lisp-mailer LALR parser generator
C02104 00512 ∂10-Nov-88 1311 Common-Lisp-mailer backquote
C02108 00513 ∂10-Nov-88 1350 Common-Lisp-mailer backquote
C02115 00514 ∂10-Nov-88 1419 Common-Lisp-mailer backquote
C02117 00515 ∂10-Nov-88 1455 Common-Lisp-mailer backquote
C02121 00516 ∂10-Nov-88 1603 Common-Lisp-mailer backquote
C02124 00517 ∂10-Nov-88 1651 Common-Lisp-mailer Re: backquote
C02127 00518 ∂10-Nov-88 2222 Common-Lisp-mailer backquote
C02130 00519 ∂11-Nov-88 0941 Common-Lisp-mailer Re: backquote
C02138 00520 ∂11-Nov-88 0959 Common-Lisp-mailer backquote
C02141 00521 ∂11-Nov-88 1020 Common-Lisp-mailer backquote
C02147 00522 ∂11-Nov-88 1804 Common-Lisp-mailer Re: backquote
C02150 00523 ∂13-Nov-88 1538 Common-Lisp-mailer backquote
C02160 00524 ∂13-Nov-88 2008 Common-Lisp-mailer backquote
C02163 00525 ∂14-Nov-88 0007 Common-Lisp-mailer backquote
C02165 00526 ∂14-Nov-88 0843 Common-Lisp-mailer backquote
C02169 00527 ∂14-Nov-88 0918 Common-Lisp-mailer nested backquotes
C02173 00528 ∂14-Nov-88 1027 Common-Lisp-mailer nested backquotes
C02180 00529 ∂14-Nov-88 1350 Common-Lisp-mailer nested backquotes
C02185 00530 ∂14-Nov-88 1438 Common-Lisp-mailer nested backquotes
C02188 00531 ∂14-Nov-88 1817 Common-Lisp-mailer Re: nested backquotes
C02190 00532 ∂16-Nov-88 1003 Common-Lisp-mailer nested backquotes
C02193 00533 ∂16-Nov-88 1158 Common-Lisp-mailer Re: nested backquotes
C02195 00534 ∂16-Nov-88 1241 Common-Lisp-mailer Remove amellor@bbn.com please
C02196 00535 ∂16-Nov-88 1500 Common-Lisp-mailer nested backquotes
C02199 00536 ∂18-Nov-88 0233 Common-Lisp-mailer backquote
C02201 00537 ∂18-Nov-88 1041 Common-Lisp-mailer backquote
C02205 00538 ∂28-Nov-88 1745 Common-Lisp-mailer inconsistency in backquote spec?
C02208 00539 ∂29-Nov-88 0014 Common-Lisp-mailer inconsistency in backquote spec?
C02211 00540 ∂29-Nov-88 0813 Common-Lisp-mailer Common Lisp for SUNS
C02213 00541 ∂29-Nov-88 0906 Common-Lisp-mailer Common Lisp for SUNS
C02216 00542 ∂29-Nov-88 0937 Common-Lisp-mailer inconsistency in backquote spec?
C02220 00543 ∂29-Nov-88 1009 Common-Lisp-mailer Common Lisp for SUNS
C02225 00544 ∂29-Nov-88 1035 Common-Lisp-mailer Re: inconsistency in backquote spec?
C02233 00545 ∂29-Nov-88 1050 Common-Lisp-mailer inconsistency in backquote spec?
C02237 00546 ∂29-Nov-88 1127 Common-Lisp-mailer Re: Common Lisp for SUNS
C02240 00547 ∂29-Nov-88 1138 Common-Lisp-mailer inconsistency in backquote spec?
C02245 00548 ∂29-Nov-88 1353 Common-Lisp-mailer Re: Common Lisp for SUNS
C02251 00549 ∂29-Nov-88 1430 Common-Lisp-mailer inconsistency in backquote spec?
C02255 00550 ∂29-Nov-88 2057 Common-Lisp-mailer Common Lisp for SUNS
C02259 00551 ∂30-Nov-88 1856 Common-Lisp-mailer commonlisp types
C02262 00552 ∂01-Dec-88 0807 Common-Lisp-mailer commonlisp types
C02267 00553 ∂01-Dec-88 2205 Common-Lisp-mailer Re: commonlisp types
C02269 00554 ∂02-Dec-88 0804 Common-Lisp-mailer Re: commonlisp types
C02272 00555 ∂02-Dec-88 0810 Common-Lisp-mailer Re: Common Lisp for SUNS
C02282 00556 ∂02-Dec-88 0836 Common-Lisp-mailer commonlisp types
C02286 00557 ∂04-Dec-88 2318 Common-Lisp-mailer Re: Common Lisp for SUNS
C02293 00558 ∂05-Dec-88 1836 Common-Lisp-mailer CLtL for HP9000?
C02295 00559 ∂06-Dec-88 2147 Common-Lisp-mailer commonlisp types
C02298 00560 ∂07-Dec-88 0740 Common-Lisp-mailer #+ and *read-supress*
C02302 ENDMK
C⊗;
∂04-Jan-88 0929 Common-Lisp-mailer Question about declaration
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.STANFORD.EDU with TCP; 4 Jan 88 09:29:08 PST
Received: from XX.LCS.MIT.EDU (XX.LCS.MIT.EDU) by ACORN.CS.ROCHESTER.EDU via INTERNET with SMTP id 27125; 4 Jan 88 12:29:22 EST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 4 Jan 88 12:26-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 74460; 4 Jan 88 12:25:54-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 91173; Mon 4-Jan-88 11:20:45-EST
Date: Mon, 4 Jan 88 11:27 est
From: mike%acorn@oak.lcs.mit.edu
To: RWK@YUKON.SCRC.Symbolics.COM
Subject: Question about declaration
Cc: mike%acorn@oak.lcs.mit.edu, miller@cs.rochester.edu,
CL@ACORN.CS.ROCHESTER.EDU
Yes, but you haven't really declared those values, have you?
All you've done is declare that you can have a "list of them".
Now, if there was a "sequence-enumerated" type (as we have
in our UIMS), this would be a different matter. I.e.
(function foo ((and list (sequence-enumerated
symbol integer symbol integer)))
(values &rest (and list (sequence-enumerated
symbol integer symbol integer))))
But what you'd *like* to know here is that the individual elements are
integers;
i.e.
(function foo ((list integer))
(values &rest (list integer)))
where the new argument to LIST does *NOT* work like ARRAY (meaning "a kind of
list specialized to contain only integers"), but rather means "a list whose
elements are all INTEGER's".
There is a big gap between being able to declare the existence of
a variable number of arguments or values and being able to declare
their type.
It is possible to define (deftype LIST-OF (ty) ...) such that
(function foo (&rest (list-of integer)) (values &rest (list-of fixnum))))
makes sense. This can't be done in the normal way with
SATISFIES, but can be done by consing up a gensym and attaching the
list-of predicate to it. This is one of the uglier kludges in Common
Lisp, since it is a workaround for the lack of parameterized types.
The unresolved and truly ambiguous problem is whether &REST LIST means
that the rest arg is a list (as usual) or that the elements of the
&REST arg are lists.
Another ambiguity is whether returning type T allows the returning
of any number of values, i.e., is T > (values T T), or
T > (values &rest T).
...mike beckerle
∂04-Jan-88 1424 Common-Lisp-mailer &REST lists
Received: from [128.81.41.109] by SAIL.STANFORD.EDU with TCP; 4 Jan 88 14:24:39 PST
Received: from WINTER.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 156025; Mon 4-Jan-88 16:41:51 EST
Date: Mon, 4 Jan 88 16:41 EST
From: Charles Hornig <Hornig@ALDERAAN.SCRC.Symbolics.COM>
Subject: &REST lists
To: common-lisp@sail.stanford.edu
Message-ID: <19880104214147.6.HORNIG@WINTER.SCRC.Symbolics.COM>
Is there general agreement on whether it is valid Common Lisp to
destructively modify (RPLACA, RPLACD) the list to which a &REST
parameter is bound? I can't find a reference in CLtL for this.
∂04-Jan-88 1728 Common-Lisp-mailer &REST lists
Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 4 Jan 88 17:28:21 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU.#Internet>; Mon 4 Jan 88 20:28:01-EST
Date: Mon, 4 Jan 1988 20:27 EST
Message-ID: <FAHLMAN.12364037774.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST lists
In-reply-to: Msg of 4 Jan 1988 16:41-EST from Charles Hornig <Hornig at ALDERAAN.SCRC.Symbolics.COM>
Is there general agreement on whether it is valid Common Lisp to
destructively modify (RPLACA, RPLACD) the list to which a &REST
parameter is bound? I can't find a reference in CLtL for this.
I think there's general agreement that &rest args are supposed to be
righteous lists with indefinite extent, so RPLAC'ing them ought to be
legal.
However, this was one part of the Common Lisp spec that several early
implementations deliberately chose to deviate from in the interest of
greater efficiency. (Symbolics and TI were able to gain considerable
efficiency by consing rest args on the stack.) Both companies had plans
to fix this eventually, stack-consing only when the compiler could prove
it was safe to do so, but I don't know if this has finally been
accomplished and distributed to all users.
-- Scott
∂05-Jan-88 0031 Common-Lisp-mailer &REST lists
Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 5 Jan 88 00:30:26 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 5 Jan 88 03:29-EST
Received: from JASPER.Palladian.COM (JASPER.Palladian.COM) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 74582; 5 Jan 88 03:14:49-EST
Received: from DWORKIN.Palladian.COM (DWORKIN.Palladian.COM) by JASPER.Palladian.COM via INTERNET with SMTP id 7495; 5 Jan 88 02:12:05 EST
Date: Tue, 5 Jan 88 02:12 EST
From: Glenn S. Burke <gsb@JASPER.Palladian.COM>
Subject: &REST lists
To: Fahlman@C.CS.CMU.EDU, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <FAHLMAN.12364037774.BABYL@C.CS.CMU.EDU>
Message-ID: <880105021220.5.GSB@DWORKIN.Palladian.COM>
Reply-To: Glenn S. Burke <GSB%Jasper@LIVE-OAK.LCS.MIT.EDU>
Date: Mon, 4 Jan 1988 20:27 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Is there general agreement on whether it is valid Common Lisp to
destructively modify (RPLACA, RPLACD) the list to which a &REST
parameter is bound? I can't find a reference in CLtL for this.
I think there's general agreement that &rest args are supposed to be
righteous lists with indefinite extent, so RPLAC'ing them ought to be
legal.
I think it is legal for APPLY to pass user-specified list structure to
the function; if so the &REST list should be treated as read-only, as it
well might be. I can't remember this for sure.
∂05-Jan-88 1225 Common-Lisp-mailer &REST lists
Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 5 Jan 88 12:25:47 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 5 Jan 88 10:59:40 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 5 Jan 88 10:59:18 EST
Date: Tue, 5 Jan 88 10:59 EST
From: Barry Margolin <barmar@Think.COM>
Subject: &REST lists
To: Glenn S. Burke <GSB%Jasper@live-oak.lcs.mit.edu>
Cc: Fahlman@c.cs.cmu.edu, common-lisp@sail.stanford.edu
In-Reply-To: <880105021220.5.GSB@DWORKIN.Palladian.COM>
Message-Id: <880105105957.3.BARMAR@OCCAM.THINK.COM>
Date: Tue, 5 Jan 88 02:12 EST
From: Glenn S. Burke <gsb@jasper.palladian.com>
I think it is legal for APPLY to pass user-specified list structure to
the function; if so the &REST list should be treated as read-only, as it
well might be.
That doesn't follow. Just because you pass a read-only list to APPLY
doesn't mean that it has to use that same list when it invokes the
function. APPLY could COPY-LIST it. Or in an implementation that uses
stack-consed &REST args the list elements might be copied to the stack.
barmar
∂06-Jan-88 2359 Common-Lisp-mailer TYPEP warp implications
Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 6 Jan 88 23:59:22 PST
Received: by labrea.stanford.edu; Wed, 6 Jan 88 23:59:09 PST
Received: from bhopal.lucid.com by edsel id AA00715g; Wed, 6 Jan 88 23:18:53 PST
Received: by bhopal id AA15243g; Wed, 6 Jan 88 23:21:16 PST
Date: Wed, 6 Jan 88 23:21:16 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8801070721.AA15243@bhopal.lucid.com>
To: labrea!common-lisp%sail@labrea.stanford.edu
Subject: TYPEP warp implications
Recent mail under the subject line of "Types in CL" brought to light an
inconsistency in CLtL that may have gone unnoticed by most people.
-- The second paragraph of page 11 makes it clear that "data types" are
just sets of objects; subsequent discussion makes it clear that the
second argument to TYPEP (a type specifier) is a name for some such
set, and that there may be several distinct names specifying the same
set (or type). The first paragraph of section 6.2.1 on page 72 says
that TYPEP is a set membership test, and SUBTYPEP is a subset test.
-- The first two paragraphs of section 4.5, on page 45, describe a
permission for what I call "element-type upgrading" on arrays; the
documentation fo ARRAY-ELEMENT-TYPE on page 291 also makes it clear
that a conforming implementation is permitted to "collapse" array
element types into some more limited set of types, providing that
the array returned by make-array is at most an "upgrade".
For example, depending on how primitive arrays are actually implemented,
(make-array <dims> :element-type '(signed-byte 5))
and
(make-array <dims> :element-type '(signed-byte 16))
might legitimately create exactly the same set of objects. The only
constraint seems to be that that (array (signed-byte 16)) be the most
specific type *** in that implementation *** which can hold all the
objects made by (make-array <dims> :element-type '(signed-byte 5)).
In this case, we say that the array element type has been upgraded from
(signed-byte 5) to (signed-byte 16), and we imply that there is no
particular special provisions for arrays of element type, say,
(signed-byte 8). [Every vendor's implementation I have looked at does some
amount of non-trivial "upgrading" on the element type (signed-byte 5).]
By the bulletted paragraphs above, (array (signed-byte 5)) and
(array (signed-byte 16)) are in fact names for exactly the same
set of objects.
However pages 45 and 46 go at length to specify that these two different
names for the same set of objects must be treated differently by TYPEP
and SUBTYPEP. This seems to "warp" the utility of TYPEP since it puts
it at variance with the fundamental principle: "SUBTYPEP means subsetp".
No one I've asked has tried to defend this "warp". I conjecture that it
was added to CLtL in a mistaken belief that it would promote portability.
I say "mistaken" because the source of non-portability is the permission
to upgrade; if two different implementations do any upgrading differently,
then the effect will be the same kind of non-portability that results
when two different implementations set the boundary between fixnums and
bignums differently.
Yet I'm in favor of the permission to upgrade; I would not like to see CL
become a language like C where there are a prescribed set of kinds of arrays
that must be implemented (e.g, "int", "long int", "single", "double" etc),
and no others can exist. In short, I would not want to gain portability
at the expense of limiting the language to the architectural features of
the hardware on which it was first implemented.
I would like to suggest that the flaw be fixed as follows:
-- Delete all the documentation that suggests the :element-type argument
to make-array mignt not be a satisfactory element-type in the type
specifier for the kind of array produced;
-- Introduce a function UPGRADE-ARRAY-ELEMENT-TYPE, which will tell you
how a particular :element-type argument to make-array will be treated
(so that you don't have to cons up an array to find out).
Does anyone have any strong feeling on this dichotomy one way or the other?
Have you been affected by variations in the vendors treatement of arrays?
-- JonL --
P.S. A clarifying note on the definition of "type specifier". I called it
a "name" in the above message. This means that it is either a symbol
like FIXNUM, or ARRAY, or one of the permissible list conbinations
of type specifiers like (OR FIXNUM BIGNUM) etc. [But note that he
Object System proposal may have to permit class-objects themselves to
be considered as type-specifiers because it is possible to create classes
that don't have (proper) symbolic names; however, we can still view
"the object itself" as its own name in the sense that the address of
an object is a hidden name.] Thus the set of type-specifiers forms
a mathematical language, and the SUBTYPEP relation is generated by some
basic, generating set of relations between these names. I want to see
this language actually describing the implementation in which it is
running -- that the objects of the implementation are a model for that
language -- rather than seeing it be limited to some theoretical
model which no vendor bothers to implement.
∂07-Jan-88 0759 Common-Lisp-mailer the array type mess....
Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 7 Jan 88 07:58:55 PST
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA19342; Thu, 7 Jan 88 08:58:56 MST
Received: by orion.utah.edu (5.54/utah-1.0-slave)
id AA29760; Thu, 7 Jan 88 08:58:52 MST
Date: Thu, 7 Jan 88 08:58:52 MST
From: sandra%orion@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8801071558.AA29760@orion.utah.edu>
Subject: the array type mess....
To: edsel!jonl@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu
I believe that an implementation is not allowed to upgrade all array types
arbitrarily; at least, on p. 34, it says that the types simple-vector,
simple-string, and simple-bit-vector are disjoint.
I'm also unhappy with the current situation, but my solution would be
to do away with the array upgrading entirely. In other words, I'd like
to see (typep (make-array n :element-type foo) foo) be true in all
implementations, for all types foo. If an implementation does not have
a specialized representation for (array (signed-byte 5)), it could
still internally upgrade it to some other convenient representation,
but it should keep the original element-type around (stored in the
array header) so type discrimination will still work.
Also, the last type I asked the question, there seemed to be general
agreement that SUBTYPEP should reflect the actual type hierarchy in the
implementation. In some implementations, for example, FLOAT might be
a subtype of SHORT-FLOAT.
-Sandra
-------
∂07-Jan-88 1005 Common-Lisp-mailer &REST lists
Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 7 Jan 88 10:05:12 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 7 Jan 88 13:04-EST
Received: from JASPER.Palladian.COM (JASPER.Palladian.COM) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 74938; 7 Jan 88 12:26:14-EST
Received: from DWORKIN.Palladian.COM (DWORKIN.Palladian.COM) by JASPER.Palladian.COM via INTERNET with SMTP id 14512; 6 Jan 88 22:24:37 EST
Date: Wed, 6 Jan 88 22:25 EST
From: Glenn S. Burke <gsb@JASPER.Palladian.COM>
Subject: &REST lists
To: barmar@Think.COM
cc: common-lisp@sail.stanford.edu
In-Reply-To: <880105105957.3.BARMAR@OCCAM.THINK.COM>
Message-ID: <880106222504.9.GSB@DWORKIN.Palladian.COM>
Reply-To: Glenn S. Burke <GSB%Jasper@LIVE-OAK.LCS.MIT.EDU>
Date: Tue, 5 Jan 88 10:59 EST
From: Barry Margolin <barmar@Think.COM>
Date: Tue, 5 Jan 88 02:12 EST
From: Glenn S. Burke <gsb@jasper.palladian.com>
I think it is legal for APPLY to pass user-specified list structure to
the function; if so the &REST list should be treated as read-only, as it
well might be.
That doesn't follow. Just because you pass a read-only list to APPLY
doesn't mean that it has to use that same list when it invokes the
function. APPLY could COPY-LIST it. Or in an implementation that uses
stack-consed &REST args the list elements might be copied to the stack.
barmar
You miss the point entirely. I am saying that if it is a permissible
implementation for apply to NOT copy a user-specified list, then proper
coding practice would be to not modify &rest lists.
I don't know or remember if APPLY is permitted to do this. This came up
back when the original stack-list/heap-list decision was made, and there
may have been a consensus on it at the time.
∂07-Jan-88 2102 Common-Lisp-mailer setf subseq question
Received: from [192.5.53.205] by SAIL.STANFORD.EDU with TCP; 7 Jan 88 21:02:34 PST
Date: Fri, 8 Jan 88 00:03 EST
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: setf subseq question
To: cl@ACORN.CS.ROCHESTER.EDU
Message-ID: <880108000333.0.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 401A CS Building, Computer Science Department, University of Rochester, Rochester NY 14627
Phone: 716-275-1118
This may already be cleared up (I don't have a copy of the definition
patchs, where can I get them?)
Pg. 248: subseq sez
"
setf may be used with subseq to destructively replace a subsequence with a
sequence of new values; see also replace.
"
I ignore replace, because it says see also, as in another function that
does something along these lines, not see that for the definition of what
the setf does...
so what should (setf (subseq "abcdef" 3 5) "z")
do?
I would say (and vote for) "abcz" but if it acts like replace, you get
"abczef".
It would be real nice to have a (destructive) function that can replace
sequences with other sequences..., e.g. like substitute where new-item is
new-sequence.
Brad Miller
------
miller@cs.rochester.edu {...allegra!rochester!miller}
Brad Miller
University of Rochester Computer Science Department
'If anything is True, this is.'
∂07-Jan-88 2139 Common-Lisp-mailer setf subseq question
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.STANFORD.EDU with TCP; 7 Jan 88 21:39:44 PST
Received: from Think.COM (THINK.COM) by ACORN.CS.ROCHESTER.EDU via INTERNET with SMTP id 27303; 8 Jan 88 00:39:31 EST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 8 Jan 88 00:27:00 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 8 Jan 88 00:26:57 EST
Date: Fri, 8 Jan 88 00:26 EST
From: Barry Margolin <barmar@Think.COM>
Subject: setf subseq question
To: miller@cs.rochester.edu
Cc: cl@acorn.cs.rochester.edu
In-Reply-To: <880108000333.0.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Message-Id: <880108002641.5.BARMAR@OCCAM.THINK.COM>
Date: Fri, 8 Jan 88 00:03 EST
From: Brad Miller <miller@acorn.cs.rochester.edu>
so what should (setf (subseq "abcdef" 3 5) "z")
do?
I vote that it is some kind of error (I'm not sure whether it should be
"is an" or "signals an"). The point of SETF is that after doing
(progn (setf <form> <val>)
<form>)
should return <val> (assuming that <form> doesn't have side-effects that
alter its return value). If the result were "abcz" then (subseq
<result> 3 5) is an error. If the result were "abczef" (which is what
Symbolics returns) then (subseq <result> 3 5) returns "ze", which isn't
the same as "z".
barmar
∂08-Jan-88 1740 Common-Lisp-mailer side-effecting functions ...
Received: from RUTGERS.EDU by SAIL.Stanford.EDU with TCP; 8 Jan 88 17:40:01 PST
Received: by RUTGERS.EDU (5.54/1.15) with UUCP
id AA02493; Fri, 8 Jan 88 18:29:12 EST
Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424)
id AA05080; Wed, 6 Jan 88 16:13:27 PST
Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424)
id AA15335; Wed, 6 Jan 88 16:14:28 PST
Date: 6 Jan 1988 16:12 PST
From: David Bein <pyrnj!pyramid!bein@RUTGERS.EDU>
Subject: side-effecting functions ...
To: common-lisp@sail.stanford.edu@RUTGERS.EDU
Message-Id: <568511807/bein@pyrnova>
[ I know this has been discussed sometime in the past, so please excuse
its new presence. ]
Suppose we are going to compile the following forms:
(1) (FUNCALL 'FOO (SETF (SYMBOL-FUNCTION 'FOO) #'NEW-FOO))
(2) (FUNCALL #'FOO (SETF (SYMBOL-FUNCTION 'FOO) #'NEW-FOO))
(3) (FOO (SETF (SYMBOL-FUNCTION 'FOO) #'NEW-FOO))
(Assume FOO is not an FLET/LABELS function..)
I am assuming that #1 uses the function definition for NEW-FOO and
that #2 uses the current definition for FOO. Should #3 behave as
#1 or #2 or is this purposefully left undefined to discourage
coding practices like this?
--David
∂08-Jan-88 2029 Common-Lisp-mailer TYPEP warp implications
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 8 Jan 88 20:29:00 PST
Received: by labrea.stanford.edu; Fri, 8 Jan 88 20:28:54 PST
Received: from bhopal.lucid.com by edsel id AA10453g; Fri, 8 Jan 88 19:17:35 PST
Received: by bhopal id AA23932g; Fri, 8 Jan 88 19:20:07 PST
Date: Fri, 8 Jan 88 19:20:07 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8801090320.AA23932@bhopal.lucid.com>
To: labrea!Masinter.PA%Xerox.COM@labrea.stanford.edu
Cc: labrea!common-lisp%sail@labrea.stanford.edu
In-Reply-To: "Larry_Masinter.PARC"@Xerox.COM's message of 8 Jan 88 14:56:16 PST (Friday) <880108-145707-2273@Xerox>
Subject: TYPEP warp implications
re: Wouldn't it be simpler, promote portability, and not cost very much to
require that arrays remember the element type they were created with?
Well, not necessarily the :element-type arguemnt per se, but a canonical
representation thereof. What you are suggesting is that we toss out
element-type "upgrading"; I could contemplate that. I wonder how others feel?
-- JonL --
∂08-Jan-88 2029 Common-Lisp-mailer the array type mess....
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 8 Jan 88 20:29:22 PST
Received: by labrea.stanford.edu; Fri, 8 Jan 88 20:29:17 PST
Received: from bhopal.lucid.com by edsel id AA10474g; Fri, 8 Jan 88 19:27:32 PST
Received: by bhopal id AA23963g; Fri, 8 Jan 88 19:30:02 PST
Date: Fri, 8 Jan 88 19:30:02 PST
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8801090330.AA23963@bhopal.lucid.com>
To: sandra%orion@cs.utah.edu
Cc: labrea!common-lisp%sail@labrea.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Thu, 7 Jan 88 08:58:52 MST <8801071558.AA29760@orion.utah.edu>
Subject: the array type mess....
re: I believe that an implementation is not allowed to upgrade all array types
arbitrarily; . . .
Quite right -- since strings and bit-arrays are treated specially in so many
contexts, I frequently forget that are also subtypes of arrays.
re: In other words, I'd like
to see (typep (make-array n :element-type foo) foo) be true in all
implementations, for all types foo.
I'm sure you meant to say:
(typep (make-array n :element-type '<foo>)
'(array <foo>))
right?
Yes, upgrading isn't the only way to optimize the important cases; although
I'd think a vendor would be under some compulsion to reveal just which
element types were "preferable".
-- JonL --
∂09-Jan-88 1255 Common-Lisp-mailer the array type mess....
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 9 Jan 88 12:54:58 PST
Received: ID <RAM@C.CS.CMU.EDU.#Internet>; Sat 9 Jan 88 15:54:18-EST
Date: Sat, 9 Jan 1988 15:54 EST
Message-ID: <RAM.12365298662.BABYL@>
Sender: RAM@λλ
From: Ram@C.CS.CMU.EDU
To: Jon L White <edsel!jonl@LABREA.STANFORD.EDU>
Cc: common-lisp@SAIL.STANFORD.EDU, sandra%orion@CS.UTAH.EDU
Subject: the array type mess....
Well, I certainly agree that there is a mess here, but it seems to me
that an obvious solution is being overlooked. It is possible to have
both implementation-dependent array specialization and the identity:
(typep (make-array ... :element-type <type>) '(array ... <type>)) => T
Array type specialization is just one instance of the implementation
process of mapping user specifications into the implementation. In
order to understand the Common Lisp type system, you have to start
thinking about two different conceptions of type:
Definitional type
This is the type system as seen by the user of the implementation.
It is a collection of promises made by the language definition to
the user.
Implementation type
This is an abstraction of the implementation chosen for an object.
The implementation type of an object is basically a name for the
representation chosen for that object, and often had more to do
with the details of the implementation of the object than with the
user visible meaning of the object. Consider the FIXNUM type or
the type that has been hypothesized in previous discussions
POWER-OF-TWO-BIGNUM. Implementation types are usually of little
direct concern to the user: his concern is to somehow use the
defined language facilities in a way that permits efficient
representations.
Traditionally, these two conceptions of type have been used largely
interchangeably in Lisp. I think that there are two main reasons for
this:
-- Before Common Lisp, Lisp systems didn't have type systems elaborate
enough to say anything very interesting about the types of objects.
In these simple systems, it was easier to maintain an approximate
equivalence between the definitional and implementation type.
-- Before Common Lisp, the distinction between the implementation and
the definition was generally only casually made. This was
acceptable, since these Lisp dialects had only one implementation.
The problem that we are seeing with arrays is that the relationship
between definitional and implementation types is under-defined,
causing problems in functions that straddle the
definition=>implementation boundary. There are two obvious solutions,
one of which has already been proposed:
-- Make the mapping more direct. Eliminating "array element type
upgrading" would be an instance of this.
-- Make the mapping explicitly ill-defined in a more useful way.
I think we need to do the latter because the former won't work. I don't
see how to eliminate "array element type upgrading" without creating
more problems we solve. Even if this can be done, the ill-defined
nature of the to-implementation mapping will crop up again and again.
We already had a long discussion about TYPE-OF, ARRAY-ELEMENT-TYPE and
SUBTYPEP. This discussion was prompted by what superficially appeared
to be compile questions about TYPE-OF.
The main reason that the problem is so blatant with arrays is that an
array is currently the only way that Common Lisp lets the user get his
hands on a specializable cell as something approaching a first-class
object. I think that array element types should treated in much the
same way as the primary other kind of specializable cell: variables.
It is widely accepted that a Common Lisp compiler is free to implement a
variable however it damn well pleases as long as it preserves the
language semantics during normal execution. When compilers start using
non-standard representations such as "unboxed numbers" and playing games
like introducing spurious copies during register allocation, then
extra-linguistic environment features such as debuggers can detect the
funny business, but this is of little concern to the normal programmer.
With arrays, it is somewhat more awkward to play free and loose with
representations, since the user has been given operations (such as
ARRAY-ELEMENT-TYPE) that manipulate the implementation type of the
object in terms of definitional types. The user has been given enough
rope to hang himself, mainly because array types were being thought of
more in terms of implementation types than definitional types.
My conclusion is that it isn't array types that are wrong, it is the
understanding of the meaning of TYPEP that is wrong. TYPEP should be
thought of as a query:
Could this value be the implementation of an object defined by the
language to have this type?
and not:
Is this the implementation type of this object?
The first definition is the only one that works in Common Lisp, since
the Common Lisp definition is implementation-independent. Under this
interpretation, it is obvious that the TYPEP/MAKE-ARRAY identity holds.
In terms of the TYPEP implementation, this means that TYPEP will
automatically do the to-implementation mapping on the type specifier
before comparing it to the implementation type.
Rob
∂14-Jan-88 2128 Common-Lisp-mailer setf subseq question
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 14 Jan 88 21:27:49 PST
Received: from STONY-BROOK.SCRC.Symbolics.COM (STONY-BROOK.SCRC.SYMBOLICS.COM) by ACORN.CS.ROCHESTER.EDU via INTERNET with SMTP id 27688; 14 Jan 88 20:37:01 EST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 320945; Thu 14-Jan-88 15:57:00 EST
Date: Thu, 14 Jan 88 15:57 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: setf subseq question
To: miller@cs.rochester.edu, Barry Margolin <barmar@Think.COM>
cc: cl@ACORN.CS.ROCHESTER.EDU
In-Reply-To: <880108000333.0.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>,
<880108002641.5.BARMAR@OCCAM.THINK.COM>
Message-ID: <19880114205717.7.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 8 Jan 88 00:03 EST
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Pg. 248: subseq sez
"
setf may be used with subseq to destructively replace a subsequence with a
sequence of new values; see also replace.
"
I ignore replace, because it says see also, as in another function that
does something along these lines, not see that for the definition of what
the setf does...
so what should (setf (subseq "abcdef" 3 5) "z")
do?
The answer is on page 95, near the bottom of the page. It changes
the constant "abcdef" to "abczef". CLtL suffers from poor cross-referencing.
I would say (and vote for) "abcz" but if it acts like replace, you get
"abczef".
There is no way SETF could change the length of the sequence if it was not
either an adjustable array or one with a fill-pointer.
It would be real nice to have a (destructive) function that can replace
sequences with other sequences..., e.g. like substitute where new-item is
new-sequence.
I think you mean a function that is to SUBSTITUTE as SEARCH is to POSITION.
I agree that this is useful; of course, it's not hard to write for yourself
if you don't care about machine-dependent efficiency optimizations.
Date: Fri, 8 Jan 88 00:26 EST
From: Barry Margolin <barmar@Think.COM>
The point of SETF is that after doing
(progn (setf <form> <val>)
<form>)
should return <val> (assuming that <form> doesn't have side-effects that
alter its return value). If the result were "abcz" then (subseq
<result> 3 5) is an error. If the result were "abczef" (which is what
Symbolics returns) then (subseq <result> 3 5) returns "ze", which isn't
the same as "z".
It's true that the way CLtL defines SETF of SUBSEQ violates that aphorism
about setf. I don't see any way to define it that would be consistent
with the aphorism, other than to forbid the two lengths to differ. I'm
not going to defend the current definition of SETF of SUBSEQ as right;
in this message I'm just telling you what CLtL says.
∂15-Jan-88 1440 Common-Lisp-mailer fill-pointer
Received: from ucbvax.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 15 Jan 88 14:39:46 PST
Received: by ucbvax.Berkeley.EDU (5.58/1.26)
id AA20084; Fri, 15 Jan 88 09:26:49 PST
Received: by lcuxle.UUCP (4.6/4.2)
id AA08855; Fri, 15 Jan 88 11:37:22 EST
Date: Fri, 15 Jan 88 11:37:22 EST
From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia)
Message-Id: <8801151637.AA08855@lcuxle.UUCP>
To: common-lisp@sail.stanford.edu
Subject: fill-pointer
If a vector X has been defined with a fill pointer, then should the
following be valid?
(SETF (FILL-POINTER X) T)
On page 296 of CLtL, it would seem that it is not valid:
"SETF may be used with FILL-POINTER to change the fill pointer of a
vector. The fill pointer of a vector must always be an integer between
zero and the size of the vector (inclusive)."
However, since T is allowed at the time the vector is defined (see page 288),
then why not when changing it? It would seem convenient to restore a
vector X that has a fill pointer to its full size without having to find its
value with (ARRAY-DIMENSION X 0), or some other comparable function.
Of the implementations that I've looked at, TI allows
(SETF (FILL-POINTER X) T), while KCL and XEROX do not. CL allowed it,
but erroneously since it actually put T into the fill pointer and that
messed up accesses to X.
∂15-Jan-88 1511 Common-Lisp-mailer fill-pointer
Received: from ucbvax.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 15 Jan 88 14:39:46 PST
Received: by ucbvax.Berkeley.EDU (5.58/1.26)
id AA20084; Fri, 15 Jan 88 09:26:49 PST
Received: by lcuxle.UUCP (4.6/4.2)
id AA08855; Fri, 15 Jan 88 11:37:22 EST
Date: Fri, 15 Jan 88 11:37:22 EST
From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia)
Message-Id: <8801151637.AA08855@lcuxle.UUCP>
To: common-lisp@sail.stanford.edu
Subject: fill-pointer
If a vector X has been defined with a fill pointer, then should the
following be valid?
(SETF (FILL-POINTER X) T)
On page 296 of CLtL, it would seem that it is not valid:
"SETF may be used with FILL-POINTER to change the fill pointer of a
vector. The fill pointer of a vector must always be an integer between
zero and the size of the vector (inclusive)."
However, since T is allowed at the time the vector is defined (see page 288),
then why not when changing it? It would seem convenient to restore a
vector X that has a fill pointer to its full size without having to find its
value with (ARRAY-DIMENSION X 0), or some other comparable function.
Of the implementations that I've looked at, TI allows
(SETF (FILL-POINTER X) T), while KCL and XEROX do not. CL allowed it,
but erroneously since it actually put T into the fill pointer and that
messed up accesses to X.
∂15-Jan-88 1724 Common-Lisp-mailer fill-pointer
Received: from ucbvax.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 15 Jan 88 14:39:46 PST
Received: by ucbvax.Berkeley.EDU (5.58/1.26)
id AA20084; Fri, 15 Jan 88 09:26:49 PST
Received: by lcuxle.UUCP (4.6/4.2)
id AA08855; Fri, 15 Jan 88 11:37:22 EST
Date: Fri, 15 Jan 88 11:37:22 EST
From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia)
Message-Id: <8801151637.AA08855@lcuxle.UUCP>
To: common-lisp@sail.stanford.edu
Subject: fill-pointer
If a vector X has been defined with a fill pointer, then should the
following be valid?
(SETF (FILL-POINTER X) T)
On page 296 of CLtL, it would seem that it is not valid:
"SETF may be used with FILL-POINTER to change the fill pointer of a
vector. The fill pointer of a vector must always be an integer between
zero and the size of the vector (inclusive)."
However, since T is allowed at the time the vector is defined (see page 288),
then why not when changing it? It would seem convenient to restore a
vector X that has a fill pointer to its full size without having to find its
value with (ARRAY-DIMENSION X 0), or some other comparable function.
Of the implementations that I've looked at, TI allows
(SETF (FILL-POINTER X) T), while KCL and XEROX do not. CL allowed it,
but erroneously since it actually put T into the fill pointer and that
messed up accesses to X.
∂18-Jan-88 1543 Common-Lisp-mailer (simulated) multiprocessor extensions to Common Lisp?
Received: from hecuba.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 18 Jan 88 15:43:22 PST
Received: by hecuba.Berkeley.EDU (5.57/1.25)
id AA06672; Mon, 18 Jan 88 15:44:01 PST
Message-Id: <8801182344.AA06672@hecuba.Berkeley.EDU>
To: common-lisp@sail.stanford.edu
Subject: (simulated) multiprocessor extensions to Common Lisp?
Date: Mon, 18 Jan 88 15:43:57 PST
From: Benjamin Zorn <zorn%hecuba.Berkeley.EDU@Berkeley.EDU>
I work for the SPUR project at UC Berkeley and we are in the process
of building a multiprocessor Lisp workstation. SPUR Lisp will be
superset of Common Lisp with multiprocessor extensions including
futures. I am gathering multiprocessor Lisp programs and would be
very interested in hearing about any applications that we could use to
test and demonstrate our system. Furthermore, if anyone has
implemented simulated futures as an extension to any version of Common
Lisp I would be grateful to hear about it. I have heard rumors about
versions of Multilisp implemented for Lisp machines and would be happy
to know if this code is available. My goal is to test multiprocessor
SPUR Lisp programs before the SPUR hardware is available and if I can
take advantage of future implementations for other Common Lisp
systems, I would appreciate it.
-Ben Zorn (zorn@ernie.berkeley.edu)
∂19-Jan-88 0502 Common-Lisp-mailer Scheme standard?
Received: from A.ISI.EDU by SAIL.Stanford.EDU with TCP; 19 Jan 88 05:02:07 PST
Date: 19 Jan 1988 08:00-EST
Sender: MATHIS@A.ISI.EDU
Subject: Scheme standard?
From: MATHIS@A.ISI.EDU
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[A.ISI.EDU]19-Jan-88 08:00:42.MATHIS>
I have heard second-hand that the IEEE is considering doing a
standard for Scheme. Does anyone know anything about this or how
I could get in touch with the people involved? Thanks, Bob
∂20-Jan-88 0007 Common-Lisp-mailer circular structure syntax
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 20 Jan 88 00:07:06 PST
Date: 19 Jan 88 23:29:28 EST
From: Timothy Daly <DALY@ibm.com>
To: common-lisp@sail.stanford.edu
Message-Id: <011988.232929.daly@ibm.com>
Subject: circular structure syntax
Is there a SCHEME syntax for circular structures?
That is, what is the SCHEME equivalent syntax for:
#1=(defun foo () (print '#1#))
I've checked every report I can find and all of the PC Scheme
manual (will online documentation ever be a reality? Will there
ever be a copy of CLtL online?) without finding mention of the
subject.
tim
DALY@IBM.COM
IBM T.J.Watson Research Center
Yorktown Heights, N.Y.
∂22-Jan-88 1831 Common-Lisp-mailer type declarations of special bindings
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 22 Jan 88 18:31:21 PST
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA00256@EDDIE.MIT.EDU>; Fri, 22 Jan 88 21:30:12 EST
Received: by spt.entity.com (smail2.5); 22 Jan 88 18:12:35 EST (Fri)
To: common-lisp@sail.stanford.edu
Subject: type declarations of special bindings
Message-Id: <8801221812.AA05095@spt.entity.com>
Date: 22 Jan 88 18:12:35 EST (Fri)
From: gz@spt.entity.com (Gail Zacharias)
In the following example, does the fixnum declaration apply to the
inner reference to X (in the setq)?
(let ((X 17))
(declare (special X) (fixnum X))
(let ((X 'local))
(locally
(declare (special X))
(setq X (foo)))))
∂22-Jan-88 2323 Common-Lisp-mailer Type specifiers in THE constructs
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Jan 88 23:23:07 PST
Received: by labrea.Stanford.EDU; Fri, 22 Jan 88 23:23:10 PST
Received: from bhopal.lucid.com by edsel id AA29335g; Fri, 22 Jan 88 22:04:19 PST
Received: by bhopal id AA04525g; Fri, 22 Jan 88 22:07:47 PST
Date: Fri, 22 Jan 88 22:07:47 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801230607.AA04525@bhopal.lucid.com>
To: labrea!common-lisp%su-ai@labrea.Stanford.EDU
Subject: Type specifiers in THE constructs
Does the type-specifier in (THE <type-spec> (MUMBLE)) refer to the type
of the first value (of zero or more values) returned by (MUMBLE), or does
it refer to the multiple-value spectrum? In short, is is a shorthand for
1. (THE (VALUES <type-spec> &REST T) (MUMBLE))
or for
2. (THE (VALUES <type-spec>) (MUMBLE))
Of the five implementations I've looked at, three do it like the former and
two do it like the latter.
Wording on CLtL p161 seems to suggest a meaning like the former:
"For this purpose the THE special form is defined; (THE TYPE FORM)
means that the value of FORM is declared to be of type TYPE."
Note that it says "the value of FORM", not "the values of FORM". Also
supporting the latter is the documentation of (VALUES ...) as a type
specifier, on CLtL p48: "It is used to specify individual types when
multiple values are involved"; i.e., an exception to the "normal" case
of specifying "the value" is made when you want to talk about the other
return values.
Wording on CLtL p138 seems to suggest the latter; namely THE "passes
back" multiple values, so the <type-spec> might want to refer to the
spectrum being "passed back". Note that this interpretation makes
(THE NUMBER (TRUNCATE 10 3)) an illegal form.
-- JonL --
∂22-Jan-88 2323 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 22 Jan 88 23:23:15 PST
Received: by labrea.Stanford.EDU; Fri, 22 Jan 88 23:23:21 PST
Received: from bhopal.lucid.com by edsel id AA29350g; Fri, 22 Jan 88 22:11:52 PST
Received: by bhopal id AA04546g; Fri, 22 Jan 88 22:15:21 PST
Date: Fri, 22 Jan 88 22:15:21 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801230615.AA04546@bhopal.lucid.com>
To: labrea!common-lisp%sail@labrea.Stanford.EDU
Subject: LEAST-POSITIVE-<mumble>-FLOAT
Does anyone care what values these "constants" actually take on? that is,
does anyone use then in any context other than test suites?
CLtL p231 says that this number should be the "number closest in value to
(but not equal to) zero provided by the implementation." In those
implementations supporting IEEE-like denormalized numbers, a question
arises: are denormalized numbers "provided", in the sense required?
Of the four such implementations I've checked, half set this constant
to the least normalized number, and half set it to the least denormalized
number.
Supporting the former is the fact that IEEE hardware, when traps are
enabled, will signal an underflow trap whenever a result would be less
than the least normalized number. Supporting the latter is the fact
that under at least mode of operation of the hardware, denormalized
numbers are "provided" by the implementation.
-- JonL --
∂23-Jan-88 0125 Common-Lisp-mailer type declarations of special bindings
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 23 Jan 88 01:22:30 PST
Received: by labrea.Stanford.EDU; Sat, 23 Jan 88 01:22:39 PST
Received: from bhopal.lucid.com by edsel id AA29772g; Sat, 23 Jan 88 01:14:53 PST
Received: by bhopal id AA05388g; Sat, 23 Jan 88 01:18:23 PST
Date: Sat, 23 Jan 88 01:18:23 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801230918.AA05388@bhopal.lucid.com>
To: gz@spt.entity.com
Cc: labrea!common-lisp%sail@labrea.Stanford.EDU
In-Reply-To: Gail Zacharias's message of 22 Jan 88 18:12:35 EST (Fri) <8801221812.AA05095@spt.entity.com>
Subject: type declarations of special bindings
re: In the following example, does the fixnum declaration apply to the
inner reference to X (in the setq)?
(let ((X 17))
(declare (special X) (fixnum X))
(let ((X 'local))
(locally
(declare (special X))
(setq X (foo)))))
CLtL, p 158 says that type declarations affect the binding "and specifies
that the variable[s] mentioned will take on values only of the specified
type". The inner reference is to the variable bound specially, not to
the one bound locally, so it is the same variable whose binding was
declared fixnum. Hence, in theory, it should be as if the form
(setq X (foo))
were written as
(setq X (the fixnum (foo)))
but I suspect very few, if any, compilers actually make this leap of type
inferencing.
-- JonL --
∂23-Jan-88 1212 Common-Lisp-mailer Re: Type specifiers in THE constructs
Received: from cayuga.cs.rochester.edu (CS.ROCHESTER.EDU) by SAIL.Stanford.EDU with TCP; 23 Jan 88 12:12:39 PST
Received: by cayuga.cs.rochester.edu (5.52/h) id AA13143; Sat, 23 Jan 88 15:12:40 EST
Received: from loopback by lesath.cs.rochester.edu (3.2/h) id AA04860; Sat, 23 Jan 88 15:12:35 EST
Message-Id: <8801232012.AA04860@lesath.cs.rochester.edu>
To: common-lisp@sail.stanford.edu
Subject: Re: Type specifiers in THE constructs
Date: Sat, 23 Jan 88 15:12:31 -0500
From: quiroz@cs.rochester.edu
Is there agreement that only aware callers need to know about
multiple values? I have the impression that many decisions already
in the language point to the desire to avoid burdening an unaware
caller.
If there is agreement, the best interpretation for the type
specifier in a THE form would be:
1- If the specifier is of the form (VALUES ...), then it
applies to the potentially many return values of the second
subform of THE. (Subject to someone solving the question of
what exactly &REST means.) [Doubt: I would like to say
that declaring fewer values than actually returned is OK and
declares only those, while declaring more values than
actually returned `signals an error'. Is that consistent
with the rest? This is in line with the (possibly
dangerous) assumption that if it is safe to return more than
1 value when your caller expected one exactly, it should be
fine to return more than N values when your caller is
willing to use only N of those.]
2- Otherwise, it refers to the first or only value returned.
So, I would say that (THE NUMBER (TRUNCATE 10 3)) should be legal
(should even continue returning the multiple values), but should be
read as constraining only the first of the returned values to be
NUMBERP.
=Cesar
--------
Cesar Augusto Quiroz Gonzalez
Department of Computer Science ...allegra!rochester!quiroz
University of Rochester or
Rochester, NY 14627 quiroz@cs.rochester.edu
∂24-Jan-88 0618 Common-Lisp-mailer Type specifiers in THE constructs
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 24 Jan 88 06:18:35 PST
Received: ID <RAM@C.CS.CMU.EDU.#Internet>; Sun 24 Jan 88 09:18:17-EST
Date: Sun, 24 Jan 1988 09:18 EST
Message-ID: <RAM.12369158731.BABYL@>
Sender: RAM@λλ
From: Ram@C.CS.CMU.EDU
To: Jon L White <edsel!jonl@LABREA.STANFORD.EDU>
Cc: common-lisp@SAIL.STANFORD.EDU
Subject: Type specifiers in THE constructs
Date: Saturday, 23 January 1988 01:07-EST
From: Jon L White <edsel!jonl at labrea.Stanford.EDU>
To: labrea!common-lisp%su-ai at labrea.Stanford.EDU
Re: Type specifiers in THE constructs
Does the type-specifier in (THE <type-spec> (MUMBLE)) refer to the type
of the first value (of zero or more values) returned by (MUMBLE), or does
it refer to the multiple-value spectrum? In short, is is a shorthand for
1. (THE (VALUES <type-spec> &REST T) (MUMBLE))
or for
2. (THE (VALUES <type-spec>) (MUMBLE))
I suggest the first interpretation, with a note that when the
<type-spec> is a VALUES type, THE should enforce exactly the specified
values. (which may be what you had in mind) Hence:
(THE NUMBER (TRUNCATE 10 3)) ;legal
(THE (VALUES NUMBER) (TRUNCATE 10 3)) ; illegal
I could also live with the second interpretation. I just wanted to
make clear that I consider the multiple-value semantics of THE to be
useful. Even if use of a non-values type required a single value, it
would be worth supporting THE VALUES so that multiple value results
can be declared.
Although interpretation 1 may seem a bit sleazy, it is consistent with
the general value-count sleaze in Common Lisp.
Rob
∂25-Jan-88 1408 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 25 Jan 88 14:08:14 PST
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by labrea.Stanford.EDU with TCP; Mon, 25 Jan 88 13:31:54 PST
Received: from KRYPTON.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 327496; Mon 25-Jan-88 09:38:59 EST
Date: Mon, 25 Jan 88 09:38 EST
From: Robert A. Cassels <Cassels@stony-brook.scrc.symbolics.com>
Subject: LEAST-POSITIVE-<mumble>-FLOAT
To: edsel!jonl@labrea.stanford.edu,
labrea!common-lisp%sail@labrea.stanford.edu
In-Reply-To: <8801230615.AA04546@bhopal.lucid.com>
Message-Id: <19880125143853.4.CASSELS@KRYPTON.SCRC.Symbolics.COM>
Date: Fri, 22 Jan 88 22:15:21 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Does anyone care what values these "constants" actually take on? that is,
does anyone use then in any context other than test suites?
CLtL p231 says that this number should be the "number closest in value to
(but not equal to) zero provided by the implementation." In those
implementations supporting IEEE-like denormalized numbers, a question
arises: are denormalized numbers "provided", in the sense required?
Of the four such implementations I've checked, half set this constant
to the least normalized number, and half set it to the least denormalized
number.
In Symbolics Genera 7.2, we've made the values of those constants be
denormalized to meet the letter of CLtL (they used to be normalized).
We also added some constants to the SCL: (Symbolics-Common-Lisp:)
package, like LEAST-POSITIVE-NORMALIZED-<mumble>-FLOAT.
Supporting the former is the fact that IEEE hardware, when traps are
enabled, will signal an underflow trap whenever a result would be less
than the least normalized number. Supporting the latter is the fact
that under at least mode of operation of the hardware, denormalized
numbers are "provided" by the implementation.
It's a little more complicated (as if we needed that :-). IEEE
underflow traps don't happen for addition or subtraction, just for
multiplication and division. So whether you see denormalized results
from normalized operands (without traps) depends on the operation.
[Note that any addition or subtraction which produces a denormalized
result is exact. That's not always true for multiplication or
division.]
Oh, yeah. In answer to your original question, we don't care or use
them for anything. But a customer complained, so we changed to conform
to the letter of CLtL.
-- JonL --
∂26-Jan-88 0627 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 06:27:40 PST
Received: by labrea.Stanford.EDU; Tue, 26 Jan 88 06:27:54 PST
Received: from bhopal.lucid.com by edsel id AA11820g; Tue, 26 Jan 88 06:09:43 PST
Received: by bhopal id AA19193g; Tue, 26 Jan 88 06:13:27 PST
Date: Tue, 26 Jan 88 06:13:27 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801261413.AA19193@bhopal.lucid.com>
To: labrea!Cassels%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!common-lisp%sail@labrea.Stanford.EDU
In-Reply-To: Robert A. Cassels's message of Mon, 25 Jan 88 09:38 EST <19880125143853.4.CASSELS@KRYPTON.SCRC.Symbolics.COM>
Subject: LEAST-POSITIVE-<mumble>-FLOAT
re: It's a little more complicated (as if we needed that :-). IEEE
underflow traps don't happen for addition or subtraction, just for
multiplication and division. . . .
What kind of hardware device are you describing? The MC68881 will always
give you the traps you enable, regardless of the operation. [In fact, the
present query was prompted by our noticeing that the underflow traps occur
when a denormalized result is produced -- not merely when the number is
too small to be represented at all]. Maybe you are overlooking the fact
that adding one normalized number and one unnormalized one isn't by itself
trappable -- only if the result is subsequently denormalized will the trap
occur.
re: Oh, yeah. In answer to your original question, we don't care or use
them for anything. But a customer complained, so we changed to conform
to the letter of CLtL.
Could you find out how "independent" that customer complaint is? I know
that at least one other Common Lisp product changed its view on this matter
solely because Lucid's test suite complained about it. It would be "no
information" if the customer who complained to Symbolics did so only because
he found a different resolution of the problem in Lucid Common lisp.
Bob Mathis has some knowledge of how this issue was resolved in the ADA
world. How about it Bob? any clues?
-- JonL --
∂26-Jan-88 1807 Common-Lisp-mailer Re: Type specifiers in THE constructs
Received: from REAGAN.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 18:07:30 PST
Received: from JONES.AI.MIT.EDU by REAGAN.AI.MIT.EDU via CHAOS with CHAOS-MAIL id 88650; Tue 26-Jan-88 21:06:09 EST
Date: Tue, 26 Jan 88 21:06 EST
From: Robert W. Kerns <RWK@AI.AI.MIT.EDU>
Subject: Re: Type specifiers in THE constructs
To: quiroz@cs.rochester.edu
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8801232012.AA04860@lesath.cs.rochester.edu>
Message-ID: <880126210604.3.RWK@JONES.AI.MIT.EDU>
Date: Sat, 23 Jan 88 15:12:31 -0500
From: quiroz@cs.rochester.edu
Is there agreement that only aware callers need to know about
multiple values? I have the impression that many decisions already
in the language point to the desire to avoid burdening an unaware
caller.
...
So, I would say that (THE NUMBER (TRUNCATE 10 3)) should be legal
(should even continue returning the multiple values), but should be
read as constraining only the first of the returned values to be
NUMBERP.
I concur, and for exactly the reasons you give.
It is also least likely to cause problems for existing usages.
∂26-Jan-88 1924 Common-Lisp-mailer type declarations of special bindings
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Jan 88 19:23:59 PST
Received: from reagan.ai.mit.edu by labrea.Stanford.EDU with TCP; Tue, 26 Jan 88 19:23:57 PST
Received: from JONES.AI.MIT.EDU by REAGAN.AI.MIT.EDU via CHAOS with CHAOS-MAIL id 88656; Tue 26-Jan-88 22:23:58 EST
Date: Tue, 26 Jan 88 22:23 EST
From: Robert W. Kerns <RWK@ai.ai.mit.edu>
Subject: type declarations of special bindings
To: edsel!jonl@labrea.stanford.edu
Cc: gz@spt.entity.com, labrea!common-lisp%sail@labrea.stanford.edu
In-Reply-To: <8801230918.AA05388@bhopal.lucid.com>
Message-Id: <880126222354.4.RWK@JONES.AI.MIT.EDU>
Date: Sat, 23 Jan 88 01:18:23 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
re: In the following example, does the fixnum declaration apply to the
inner reference to X (in the setq)?
(let ((X 17))
(declare (special X) (fixnum X))
(let ((X 'local))
(locally
(declare (special X))
(setq X (foo)))))
CLtL, p 158 says that type declarations affect the binding "and specifies
that the variable[s] mentioned will take on values only of the specified
type". The inner reference is to the variable bound specially, not to
the one bound locally, so it is the same variable whose binding was
declared fixnum. Hence, in theory, it should be as if the form
(setq X (foo))
were written as
(setq X (the fixnum (foo)))
but I suspect very few, if any, compilers actually make this leap of type
inferencing.
-- JonL --
I agree with your interpretation.
I don't think it's much of a leap of inferencing, at least not for
any way that I would think to write a compiler. Most compilers
create some sort of "VAR" structure where information about a
variable is stored. After all, code generation has to make exactly
the same leap of inferencing, to figure out just where to get the
variable *from*.
But I have no comment as to whether existing compilers actually
do or do not (as you suggest) actually do anything with this.
My point is just that it isn't a burden for any well-designed
compiler.
Note that there's no actual obligation that the compiler generate
code to enforce it; there's just an obligation that the user not
write code which violates it. (I don't see any way a compiler
could handle this in an *illegal* way.)
∂27-Jan-88 0845 Common-Lisp-mailer , and #
Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jan 88 08:45:43 PST
Received: from SWAN.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 198288; Wed 27-Jan-88 11:25:43 EST
Date: Wed, 27 Jan 88 11:24 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Subject: , and #
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <19880127162452.0.DCP@SWAN.SCRC.Symbolics.COM>
I'm wondering (see CLtL page 351) why , is a terminating macro
character, while # is a non-terminating macro character? I've recently
wanted to write function with names like
convert-foo,bar,baz-and-quux-to-mumble
Was this a historical accident or was it intentional? Should we try
to change it for the next CLtL?
∂28-Jan-88 0424 Common-Lisp-mailer , and #
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 28 Jan 88 04:24:28 PST
Received: by labrea.Stanford.EDU; Thu, 28 Jan 88 04:24:39 PST
Received: from bhopal.lucid.com by edsel id AA23856g; Thu, 28 Jan 88 04:17:45 PST
Received: by bhopal id AA03491g; Thu, 28 Jan 88 04:21:36 PST
Date: Thu, 28 Jan 88 04:21:36 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8801281221.AA03491@bhopal.lucid.com>
To: labrea!DCP%QUABBIN.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!common-lisp%SAIL@labrea.Stanford.EDU
In-Reply-To: David C. Plummer's message of Wed, 27 Jan 88 11:24 EST <19880127162452.0.DCP@SWAN.SCRC.Symbolics.COM>
Subject: , and #
Lisps of the vintage of Lisp 1.5 used comma interchangably with space.
Perhaps this is the historical accident that makes it seem more like a
separator character than a constituent.
-- JonL --
∂28-Jan-88 0828 Common-Lisp-mailer , and #
Received: from DIAMOND.S4CC.Symbolics.COM ([128.81.51.3]) by SAIL.Stanford.EDU with TCP; 28 Jan 88 08:28:31 PST
Received: from TIGGER.S4CC.Symbolics.COM by DIAMOND.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 159784; Thu 28-Jan-88 10:51:50 EST
Date: Thu, 28 Jan 88 10:51 EST
From: P. T. Withington <PTW@DIAMOND.S4CC.Symbolics.COM>
Subject: , and #
To: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880127162452.0.DCP@SWAN.SCRC.Symbolics.COM>
Message-ID: <19880128155138.6.PTW@TIGGER.S4CC.Symbolics.COM>
Date: Wed, 27 Jan 88 11:24 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
I'm wondering (see CLtL page 351) why , is a terminating macro
character, while # is a non-terminating macro character? I've recently
wanted to write function with names like
convert-foo,bar,baz-and-quux-to-mumble
Was this a historical accident or was it intentional? Should we try
to change it for the next CLtL?
That would invalidate the cliche `(foo .,bar), which I have seen
occaisionally.
∂28-Jan-88 1025 Common-Lisp-mailer , and #
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 28 Jan 88 10:24:54 PST
Received: from OZ.AI.MIT.EDU (MC.LCS.MIT.EDU) by labrea.Stanford.EDU with TCP; Thu, 28 Jan 88 10:22:40 PST
Date: Thu, 28 Jan 1988 13:07 EST
Message-Id: <STEVER.12370248996.BABYL@MIT-OZ>
From: STEVER%OZ.AI.MIT.EDU@xx.lcs.mit.edu
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: labrea!common-lisp%SAIL@labrea.stanford.edu,
labrea!DCP%QUABBIN.SCRC.Symbolics.COM@labrea.stanford.edu
Subject: , and #
In-Reply-To: Msg of 28 Jan 1988 07:21-EST from Jon L White <edsel!jonl at labrea.Stanford.EDU>
∂28-Jan-88 1210 Common-Lisp-mailer [king@kestrel.arpa: commonlisp errors]
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 28 Jan 88 12:10:48 PST
Return-Path: <gls@Think.COM>
Received: from kali.think.com by Think.COM; Thu, 28 Jan 88 15:10:37 EST
Received: by kali.think.com; Thu, 28 Jan 88 15:10:32 EST
Date: Thu, 28 Jan 88 15:10:32 EST
From: gls@Think.COM
Message-Id: <8801282010.AA10925@kali.think.com>
To: common-lisp@sail.stanford.edu
Subject: [king@kestrel.arpa: commonlisp errors]
Date: Thu, 28 Jan 88 08:58:19 PDT
From: king@kestrel.arpa (Dick King)
To: steele@Think.COM
Subject: commonlisp errors
I was the one who suggested lexically scoped errors, and ability to
obtain an error environment as a storable object with limited
lifetime, for commonlisp's nascent error system. You suggested
a place to send it that was concerned with commonlisp errors; i got
nary a reply.
I am writing this note to ask for more suggestions; perhaps it should
go to the current Keepers of CommonLisp [which certainly must include
you, or at least youknow who they are] rather than a subcommittee that
may be empty or otherwise not communicating.
Thanks...
-dk
∂31-Jan-88 1442 Common-Lisp-mailer Re: LEAST-POSITIVE-<mumble>-FLOAT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 31 Jan 88 14:42:04 PST
Received: from tully.Berkeley.EDU by labrea.Stanford.EDU with TCP; Sun, 31 Jan 88 14:41:49 PST
Received: by tully.Berkeley.EDU (5.57/1.25)
id AA29857; Sun, 31 Jan 88 14:42:18 PST
From: hilfingr%tully.Berkeley.EDU@berkeley.edu (Paul Hilfinger)
Message-Id: <8801312242.AA29857@tully.Berkeley.EDU>
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: labrea!Cassels%STONY-BROOK.SCRC.Symbolics.COM@labrea.stanford.edu,
labrea!common-lisp%sail@labrea.stanford.edu
Subject: Re: LEAST-POSITIVE-<mumble>-FLOAT
In-Reply-To: Your message of Tue, 26 Jan 88 06:13:27 PST.
<8801261413.AA19193@bhopal.lucid.com>
Date: Sun, 31 Jan 88 14:42:15 PST
> Bob Mathis has some knowledge of how this issue was resolved in the ADA
> world. How about it Bob? any clues?
Having participated in most of the language reviews and maintenance of
Ada, I think I can make a definitive statement on this question. Do
NOT, under any circumstances, look to the Ada Standard for hints on
how to handle floating point arithmetic. The Standard was an attempt
to define a semantics that conformed to all existing hardware. As a
result, the properties one can deduce from the Ada semantics about
real arithmetic---in particular, about constants defined by the
language---are extremely weak and nearly useless. Indeed, as far as
denormalized numbers are concerned, the interpretation of some of the
constants is still under discussion. Denormalized numbers fall into
the crack in the semantics that includes "everything that isn't a
model number," which means numbers with more precision than required
by the model, infinities, and NaNs. As a result, they are tolerated,
but nothing specifically is said about them.
As for the interpretation of LEAST-POSITIVE-<mumble>-FLOAT, it seems
to me that the POSSIBILITY of traps is a red herring. IEEE arithmetic
also provides for a trap on an inexact result; there are cases where
it is interesting to know that such a result has been produced. Does
the fact that such a trap MIGHT be enabled raise questions about
whether (/ 1.0 3.0) must have a defined result in the case where the
trap is not enabled? If we look at the underflow trap the same way---
as indicating places in which precision is lost for a particular
reason that is sometimes but not always of interest---it seems that we
should consider the least denormalized numbers as the appropriate values
for LEAST-POSITIVE-etc.
As a (perhaps unnecessary) aside, I get a bit nervous seeing arguments
based on what a particular piece of hardware does. IEEE arithmetic is
a user interface standard, and says nothing of the division of labor
between chip and interface software. A piece of "IEEE floating-point
hardware" is entitled, for example, to produce traps at places not
mandated by the standard, as long as the accompanying support software
fills in the semantics required by the standard.
Paul Hilfinger
UC Berkeley
Hilfinger@Berkeley.EDU
∂01-Feb-88 0913 Common-Lisp-mailer LEAST-POSITIVE-<mumble>-FLOAT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 1 Feb 88 09:13:00 PST
Received: by labrea.Stanford.EDU; Mon, 1 Feb 88 09:07:38 PST
Received: from bhopal.lucid.com by edsel id AA11335g; Mon, 1 Feb 88 07:19:05 PST
Received: by bhopal id AA05000g; Mon, 1 Feb 88 07:23:13 PST
Date: Mon, 1 Feb 88 07:23:13 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802011523.AA05000@bhopal.lucid.com>
To: labrea!hilfingr%berkeley.edu@labrea.Stanford.EDU
Cc: labrea!common-lisp%sail@labrea.Stanford.EDU
In-Reply-To: Paul Hilfinger's message of Sun, 31 Jan 88 14:42:15 PST <8801312242.AA29857@tully.Berkeley.EDU>
Subject: LEAST-POSITIVE-<mumble>-FLOAT
re: [in the Ada Standard ] . . . Indeed, as far as
denormalized numbers are concerned, the interpretation of some of the
constants is still under discussion. ... [denormalized numbers] are
tolerated, but nothing specifically is said about them.
Thanks for your warnings about the continuing ferment in the ADA community on
related matters. The issue, here, is the "unexpected dividends" obtained when
trapping is turned on -- that LEAST-POSITIVE-<mumble>-FLOAT may be subject to
different interpretations depending on whether producing it is a normal or an
exceptional condition. Does ADA specify these kinds of constants? No issue
of confusion arises in Common Lisp, as far as I know, with the other elective
traps (such as the inexact trap).
re: . . . I get a bit nervous seeing arguments
based on what a particular piece of hardware does. IEEE arithmetic is
a user interface standard, and says nothing of the division of labor
between chip and interface software.
I don't think the arguments arise from any peculiarites of one chip or another;
it was just that some Common Lisp implementations defaultly had trapping turned
off, and thus no one had observed the dilemma. The IEEE Standard provides for
reasonable behaviour when a particular trap is not enabled.
What really my quest hoped to get at was "Just what value are these constants
to Common Lisp users anyway?". Who, if anyone, would be affected if their
values were changed from one state to the other? Could a user profit from
the existence of two defined constants, one normalized and the other possibly
denormalized (as Symbolics has recently done)? As long as this kind of value
is specified by the language standard (CLtL, in this case), test suites will
have a "need" for them; but beyond that, I just don't know.
-- JonL --
∂03-Feb-88 1844 Common-Lisp-mailer Issue: EXPORT-IMPORT
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 3 Feb 88 18:44:20 PST
Received: by labrea.Stanford.EDU; Wed, 3 Feb 88 18:44:35 PST
Received: from bhopal.lucid.com by edsel id AA03683g; Wed, 3 Feb 88 17:43:28 PST
Received: by bhopal id AA12513g; Wed, 3 Feb 88 17:47:47 PST
Date: Wed, 3 Feb 88 17:47:47 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802040147.AA12513@bhopal.lucid.com>
To: labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@labrea.Stanford.EDU
Cc: labrea!CL-Cleanup%SAIL@labrea.Stanford.EDU,
labrea!common-lisp%sail@labrea.Stanford.EDU
In-Reply-To: Kent M Pitman's message of Wed, 3 Feb 88 11:34 EST <880203113410.5.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Subject: Issue: EXPORT-IMPORT
The reason why some users may be mislead about EXPORT is that they fail to
heed the directive on the second line of p186: "See section 11.4 for details".
The one paragraph description of EXPORT on p186 is grossly incomplete without
reference to that other section, which cleary states: (p177, last paragraph)
"The function EXPORT takes a symbol that is *accessible* in some specified
package ... If the symbols is not accessible at all in the specified
package, a correctable error is signalled that, upon continuing, asks the
user whether the symbol should be imported." [my emphasis].
Every implementation I'm familiar with seems to implement the above
semantics rigidly; no one quietly imports the symbol without first
signalling an error.
-- JonL --
∂03-Feb-88 1949 Common-Lisp-mailer EXPORT-IMPORT and the other random commands
Received: from R20.UTEXAS.EDU by SAIL.Stanford.EDU with TCP; 3 Feb 88 19:49:34 PST
Date: Wed 3 Feb 88 21:48:23-CST
From: Bob Boyer <CL.BOYER@R20.UTEXAS.EDU>
Subject: EXPORT-IMPORT and the other random commands
To: edsel!jonl@LABREA.STANFORD.EDU
cc: labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8802040147.AA12513@bhopal.lucid.com>
Message-ID: <12371927656.13.CL.BOYER@R20.UTEXAS.EDU>
I think that the "Put in seven extremely random user
commands" stuff needs to be documented much more rigorously.
I don't think that any collection of cross-references in
CLTL will suffice to make things clear. I am no authority
on Common Lisp, but I have tried my best to use packages and
modules according to the rules I have read and according to
the implementations of the half dozen Common Lisps I could
get my hands on. I have failed, badly, and given up on the
PISERUC for the time being, pending clarification and
convergence on implementations. I stay in package USER and
don't use modules; it's rude, but it seems more portable
than the alternatives.
I think that it would be wonderful to have a test collection
of about a dozen short files that create and use about a
dozen packages, all importing and exporting from one
another, with a half dozen modules, some requiring others,
all of which interacted with compilers and loaders and Lisp
machine editors and ran under the available major Common
Lisp implementations. I do not currently believe in the
existence of such a collection of files and operations, one
which is consistent with every reasonable reading of the
PISERUC rules. I believe that someone's implementation will
break under the loading/compiling/using/requiring/editing
sequence no matter how you write such a set of files.
Whoever's implementation breaks will probably have a good
argument justifying their implementation, citing chapter and
verse from CLTL.
If an example collection of files could be agreed upon it
would, of course, still only be a start, and no substitute
for regular documentation, but it might start convergence
between implementations.
-------
∂05-Feb-88 2052 Common-Lisp-mailer EXPORT-IMPORT and the other random commands
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 5 Feb 88 20:51:47 PST
Date: Fri, 5 Feb 88 23:53:29 EST
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: EXPORT-IMPORT and the other random commands
To: CL.BOYER@R20.UTEXAS.EDU
cc: common-lisp@SAIL.STANFORD.EDU, edsel!jonl@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU
In-reply-to: Msg of Wed 3 Feb 88 21:48:23-CST from Bob Boyer <CL.BOYER at R20.UTEXAS.EDU>
Message-ID: <322177.880205.RWK@AI.AI.MIT.EDU>
Date: Wed 3 Feb 88 21:48:23-CST
From: Bob Boyer <CL.BOYER at R20.UTEXAS.EDU>
I think that the "Put in seven extremely random user
commands" stuff needs to be documented much more rigorously.
I don't think that any collection of cross-references in
CLTL will suffice to make things clear.
Frankly, I think this would be a waste of time. I don't
think ANY amount of documenting and test suites has any chance
of working. The underlying idea that you define the package
environment by performing a series of side-effects on the package
system is so wrong it is beyond repair. It is so entirely sensitive
to complex and obscure order-of-events issues that even if you
were successful in getting all implementations to do exactly the
same thing, real-life users could not adaquately standardize their
workstyles and interactions to avoid problems, even if they could
understand all the rules!
I think the time would be better spent on specifying and adopting
a DEFPACKAGE macro. This would always be the first form of the first
file loaded. (Or at least, before any IN-PACKAGE's for that package).
I think it is much easier to specify the behaviour when you don't have
to consider all the order-of-operations issues. Of course, it still needs
to be carefully specified, but the problem is more constrained, and you're
not so burdened with issues of compatibilty or programing environment
issues.
There are quite a number of us who think the DEFPACKAGE issue is important,
but so far as I know there aren't any actual proposals being written up.
∂05-Feb-88 2056 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 5 Feb 88 20:55:10 PST
Date: Fri, 5 Feb 88 23:56:53 EST
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: {Improved version} EXPORT-IMPORT and the other random commands
To: CL.BOYER@R20.UTEXAS.EDU
cc: common-lisp@SAIL.STANFORD.EDU, edsel!jonl@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU
Message-ID: <322178.880205.RWK@AI.AI.MIT.EDU>
Date: Wed 3 Feb 88 21:48:23-CST
From: Bob Boyer <CL.BOYER at R20.UTEXAS.EDU>
I think that the "Put in seven extremely random user
commands" stuff needs to be documented much more rigorously.
I don't think that any collection of cross-references in
CLTL will suffice to make things clear.
You've identified an important issue, *BUT*:
Frankly, I think this approach would be a waste of time. I don't
think ANY amount of documenting and test suites has any chance
of working. The underlying idea that you define the package
environment by performing a series of side-effects on the package
system is so wrong it is beyond repair. It is so entirely sensitive
to complex and obscure order-of-events issues that even if you
were successful in getting all implementations to do exactly the
same thing, real-life users could not adaquately standardize their
workstyles and interactions to avoid problems, even if they could
understand all the rules!
I think the time would be better spent on specifying and adopting
a DEFPACKAGE macro. This would always be the first form of the first
file loaded. (Or at least, before any IN-PACKAGE's for that package).
I think it is much easier to specify the behaviour when you don't have
to consider all the order-of-operations issues. Of course, it still needs
to be carefully specified, but the problem is more constrained, and you're
not so burdened with issues of compatibilty or programing environment
issues.
There are quite a number of us who think the DEFPACKAGE issue is important,
but so far as I know there aren't any actual proposals being written up.
Presumably the issue is one of manpower to address it, not of lack of
interest, so I would be dissapointed to see us discuss ways of "fixing"
this rather bleak area of CL, rather than working on DEFPACKAGE.
∂07-Feb-88 0015 Common-Lisp-mailer Re: {Improved version} EXPORT-IMPORT and the other random commands
Received: from tully.Berkeley.EDU ([128.32.150.44]) by SAIL.Stanford.EDU with TCP; 7 Feb 88 00:15:34 PST
Received: by tully.Berkeley.EDU (5.57/1.25)
id AA07693; Sun, 7 Feb 88 00:15:20 PST
From: hilfingr%tully.Berkeley.EDU@berkeley.edu (Paul Hilfinger)
Message-Id: <8802070815.AA07693@tully.Berkeley.EDU>
To: "Robert W. Kerns" <RWK@ai.ai.mit.edu>
Cc: CL.BOYER@r20.utexas.edu, common-lisp@sail.stanford.edu,
edsel!jonl@labrea.stanford.edu,
labrea!CL-Cleanup%SAIL@labrea.stanford.edu,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@labrea.stanford.edu
Subject: Re: {Improved version} EXPORT-IMPORT and the other random commands
In-Reply-To: Your message of Fri, 05 Feb 88 23:56:53 EST.
<322178.880205.RWK@AI.AI.MIT.EDU>
Date: Sun, 07 Feb 88 00:15:12 PST
I'm also interested in seeing the "package problem" cleared up. I
have two questions.
1) Has anyone written a definitive "why CL packages stink" article
or message, preferably one that someone regards as definitive?
2) You write
> ... The underlying idea that you define the package environment
> by performing a series of side-effects on the package system
> is so wrong it is beyond repair. It is so entirely sensitive
> to complex and obscure order-of-events issues that even if
> you were successful in getting all implementations to do
> exactly the same thing, real-life users could not adaquately
> standardize their workstyles and interactions to avoid
> problems, even if they could understand all the rules!
>
> I think the time would be better spent on specifying and
> adopting a DEFPACKAGE macro. This would always be the first
> form of the first file loaded. (Or at least, before any
> IN-PACKAGE's for that package)....
Are you saying that this DEFPACKAGE macro would NOT have any side-effects
on the package system? How would it have its effect? Or, more
generally, what is the underlying idea with which you want to
replace "side-effects on the package system"? (Somehow, electronic
mail adds an unwonted note of harshness to my syntax; that last
question was meant to be straight, not rhetorical.)
Paul Hilfinger
U. C. Berkeley
Hilfinger@Berkeley.EDU
∂07-Feb-88 0404 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 7 Feb 88 04:04:20 PST
Date: Sun, 7 Feb 88 07:04:36 EST
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: {Improved version} EXPORT-IMPORT and the other random commands
To: hilfingr%tully.Berkeley.EDU@UCBVAX.BERKELEY.EDU
cc: common-lisp@SAIL.STANFORD.EDU, CL.BOYER@R20.UTEXAS.EDU,
edsel!jonl@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU
In-reply-to: Msg of Sun 07 Feb 88 00:15:12 PST from hilfingr%tully.Berkeley.EDU at berkeley.edu (Paul Hilfinger)
Message-ID: <322657.880207.RWK@AI.AI.MIT.EDU>
Date: Sun, 07 Feb 88 00:15:12 PST
From: hilfingr%tully.Berkeley.EDU at berkeley.edu (Paul Hilfinger)
I'm also interested in seeing the "package problem" cleared up. I
have two questions.
1) Has anyone written a definitive "why CL packages stink" article
or message, preferably one that someone regards as definitive?
I don't think there's complete agreement on all the
reasons why "CL packages stink". Personally, in fact,
I think they're not bad, in use, but the setup is what
stinks. Others would disagree.
But I think there's pretty good agreement that the
seven extremely perverse functions are perverse.
2) You write
> ... The underlying idea that you define the package environment
> by performing a series of side-effects on the package system
> is so wrong it is beyond repair. It is so entirely sensitive
> to complex and obscure order-of-events issues that even if
> you were successful in getting all implementations to do
> exactly the same thing, real-life users could not adaquately
> standardize their workstyles and interactions to avoid
> problems, even if they could understand all the rules!
>
> I think the time would be better spent on specifying and
> adopting a DEFPACKAGE macro. This would always be the first
> form of the first file loaded. (Or at least, before any
> IN-PACKAGE's for that package)....
Are you saying that this DEFPACKAGE macro would NOT have any side-effects
on the package system? How would it have its effect? Or, more
generally, what is the underlying idea with which you want to
replace "side-effects on the package system"?
No, the important word up there was "series". There's no
problem with a single declarative form, at the very start.
It's when you dribble things out over several files with
a series of "functions" which have to be treated specially
by the compiler, that you start running into problems.
Not to mention the confusion factor. The very fact that this
silly mnemonic (which I can never remember) is needed to
keep the order straight should be a dead givaway that something
is wrong with splitting up declaring the package into a series
of micro-steps. You might think of these as "package microcode".
It shouldn't be supprising that there are dependencies on the
particular way an implementation does its environment.
If you declare imports, exports, inheritences, etc. at the
same time you CREATE the package, you can't have any problems
with symbols accidentally getting created before things are
set up right. (Just for one example).
(Somehow, electronic
mail adds an unwonted note of harshness to my syntax; that last
question was meant to be straight, not rhetorical.)
I know the problem. You'll notice I sent an improved version of
my note, when I noticed it sounded like I was being critical of
Bob Boyer's complaint. (Instead of urging a different approach to
solving it).
Paul Hilfinger
U. C. Berkeley
Hilfinger@Berkeley.EDU
∂07-Feb-88 0849 Common-Lisp-mailer REQUEST FOR CHANGE IN DISTRIBUTION
Received: from ari-hq1.arpa by SAIL.Stanford.EDU with TCP; 7 Feb 88 08:49:17 PST
Date: 5 Feb 88 09:36:00 EST
From: "ARTIC::HOBBS" <hobbs%artic.decnet@ari-hq1.arpa>
Subject: REQUEST FOR CHANGE IN DISTRIBUTION
To: "common-lisp" <common-lisp@sail.stanford.edu>
cc: hobbs
Reply-To: "ARTIC::HOBBS" <hobbs%artic.decnet@ari-hq1.arpa>
Dear Moderator:
I would like to request a change on your distribution list for your
Common-Lisp mailings. In an effort to conserve disk space and keep the
traffic on the DDN as low as possible, we want to handle the distribution
from one central account at our site. We have established the account
ARI_LISP for this reason. Please add the following name to your distribution
list for Common-Lisp information:
ARI_LISP@ARI-HQ1.ARPA
and please remove the following user from the distribution list:
WILLIAMS@ARI-HQ1.ARPA.
If you have any questions, please contact me through the DDN as
HOBBS@ARI-HQ1.ARPA or you may call me at 703-751-7993. Thank You.
Reginald L. Hobbs
Technical Liason for ARI-HQ1.ARPA
------
∂11-Feb-88 0120 Common-Lisp-mailer Please change my address
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 11 Feb 88 01:20:27 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa05600; 11 Feb 88 3:06 EST
Received: from ntt.jp by RELAY.CS.NET id aa11172; 11 Feb 88 2:57 EST
Received: by ntt.jp (3.2/NTT6.2cs) with TCP; Thu, 11 Feb 88 16:32:41 JST
Date: Thu, 11 Feb 88 16:32:41 JST
From: Kyoji Umemura <umemura@ntt.jp>
To: common-lisp@SAIL.STANFORD.EDU
Cc: umemura@ntt.jp
Subject: Please change my address
Please change my address
from comlisp%nttlab%nttca@Shasta to comlisp%nttlab.ntt.jp@relay.cs.net.
Thank you.
∂11-Feb-88 1637 Common-Lisp-mailer {Improved version} EXPORT-IMPORT and the other random commands
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 11 Feb 88 16:35:18 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 11 Feb 88 19:28-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 80142; 11 Feb 88 19:27:38-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 93873; Wed 10-Feb-88 16:25:21-EST
Date: Thu, 11 Feb 88 19:26 est
From: mike%acorn@oak.lcs.mit.edu
To: RWK@AI.AI.MIT.EDU
Subject: {Improved version} EXPORT-IMPORT and the other random commands
Cc: hilfingr%tully.Berkeley.EDU@UCBVAX.BERKELEY.EDU,
common-lisp@SAIL.STANFORD.EDU, CL.BOYER@R20.UTEXAS.EDU,
edsel!jonl@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU
I'm also interested in seeing the "package problem" cleared up. I
have two questions.
1) Has anyone written a definitive "why CL packages stink" article
or message, preferably one that someone regards as definitive?
I don't think there's complete agreement on all the
reasons why "CL packages stink". Personally, in fact,
I think they're not bad, in use, but the setup is what
stinks. Others would disagree.
I concur that they're ok, and even necessary for a symbolic language.
The problem I feel is that they are good for preventing "symbol"
mixups, but not "modularization". E.G., suppose you have a symbolic
differentiator, and so do I, and we don't want my dx/ds symbol to be
confused with your dx/ds symbol lest they not be able to work
together on an expression being differentiated.
Unfortunately, what packages are mostly used for is for some notion
of "modules" or "subsystems". (I agree that in lisp systems which
cons up expressions and eval or compile them that there is little
difference between these two scenarios, and we have to allow for
them, but most systems just don't do that kind of thing.) This is
why I think the notion of LOCALE's from scheme or T or whatever keeps
cropping up. My belief is that all "environment" (as opposed to
package or "obarray") based approaches to solving name conflict
problems are really designed to solve the problems of "modules" or
"subsystems" for software engineering. This is a different problem
from what packages can really solve.
But I think there's pretty good agreement that the
seven extremely perverse functions are perverse.
The last thing I saw on the subject which was under consideration by
the x3j13 compiler committee was a proposal to treat the "seven"
specially as a compiled file header. This is more than just
implicitly evaling them at compile time. Basically, this would clean up
the issue of what "side effects" these have at compile time vs.
load time of the compiled file. It would also bless specifically the
notion of a file-format for common lisp programs, thereby
making it clearly a lose to put IN-PACKAGE calls in the middle
of files, etc. This has not been firmed up yet.
What I think is needed is really a STYLE GUIDE to common lisp.
Something that says how you OUGHT to program to avoid the majority
of problems with things like the package system, etc. I think most
package problems come from misuse.
For instance, I would recommend that people be encouraged to
avoid USE-PACKAGE other than for package LISP, and instead
enumerate symbols one by one using the other package functions.
My experience is that noone wants to qualify any names so what
they do is carefully use every package that they've ever seen,
not realizing that
(let ((string "abcd"))
....)
in their code is creating a spec-bind because they are using a package
where string is a special.
nuff said.
...mike beckerle
∂12-Feb-88 0813 Common-Lisp-mailer Package Odor
Received: from nrl-aic.arpa by SAIL.Stanford.EDU with TCP; 12 Feb 88 08:13:30 PST
Return-Path: <hoey@nrl-aic.arpa>
Received: Fri, 12 Feb 88 11:11:02 EST by nrl-aic.arpa id AA02816
Date: 12 Feb 1988 10:22:34 EST (Fri)
From: Dan Hoey <hoey@nrl-aic.arpa>
Subject: Package Odor
Message-Id: <571677767/hoey@nrl-aic.arpa>
To: mike%acorn@live-oak.lcs.mit.edu
Cc: RWK@AI.AI.MIT.EDU, hilfingr%tully.Berkeley.EDU@UCBVAX.BERKELEY.EDU,
common-lisp@SAIL.STANFORD.EDU, CL.BOYER@R20.UTEXAS.EDU,
edsel!jonl@LABREA.STANFORD.EDU,
labrea!CL-Cleanup%SAIL@LABREA.STANFORD.EDU,
labrea!KMP%STONY-BROOK.SCRC.Symbolics.COM@LABREA.STANFORD.EDU
Date: Thu, 11 Feb 88 19:26 est
From: mike%acorn@oak.lcs.mit.edu
...My experience is that no one wants to qualify any names so what
they do is carefully use every package that they've ever seen,
not realizing that
(let ((string "abcd"))
....)
in their code is creating a spec-bind because they are using a package
where string is a special....
Note that this is not *quite* the problem, since STRING is a symbol in
the LISP package, and anyone who is using random packages must surely
use LISP. In that case it is the error of the other package in
proclaiming a symbol of the LISP package SPECIAL (or CONSTANT), and you
couldn't defend against the error by not using that package.
That this is an error should be made explicit--I once broke the
compiler by proclaiming LISP:FUNCTION constant, and the compiler wanted
to bind it in a macroexpansion. Making it SPECIAL might have screwed
things up beyond hope of diagnosis.
The problem of using every package is still there, though. You should
know the names of all the symbols you import (including all the symbols
exported from packages you use), not only so you don't get surprised
about them being special, but so you don't accidentally make them
special when they shouldn't be. What the package system buys you is
letting this not be all the symbols in the world.
Dan
∂12-Feb-88 1201 Common-Lisp-mailer defpackage
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Feb 88 12:00:56 PST
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA22827; Fri, 12 Feb 88 13:00:41 MST
Received: by orion.utah.edu (5.54/utah-1.0-slave)
id AA14679; Fri, 12 Feb 88 13:00:37 MST
From: sandra%orion@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8802122000.AA14679@orion.utah.edu>
Date: Fri, 12 Feb 88 13:00:34 MST
Subject: defpackage
To: common-lisp@sail.stanford.edu
While I would like to see a single DEFPACKAGE construct replace the
seven random forms, there are some problems with the order in which
things happen. Namely, since the reader would normally read the entire
DEFPACKAGE form before actually doing any of the actions it specifies,
how do you specify symbols that are to be imported or exported when
their home packages have not been created yet (perhaps because these
packages would be created during evaluation of the "require" part of
the DEFPACKAGE)? Although I don't recall that CLtL actually says
anything explicit on this point, in most implementations the reader will
signal an error if it sees an unknown package prefix on a symbol.
The best way to deal with packages that I have found so far is to use
a small DEFSYSTEM utility, and to put all the stuff to set up the
package environment for the system (including loading in of other
systems that create packages it references) at the beginning of the
file that contains the system definition.
-Sandra
-------
∂12-Feb-88 2220 Common-Lisp-mailer Package Odor
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 12 Feb 88 22:20:29 PST
Received: by labrea.Stanford.EDU; Fri, 12 Feb 88 22:20:52 PST
Received: from bhopal.lucid.com by edsel id AA19448g; Fri, 12 Feb 88 22:07:39 PST
Received: by bhopal id AA13238g; Fri, 12 Feb 88 22:12:35 PST
Date: Fri, 12 Feb 88 22:12:35 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802130612.AA13238@bhopal.lucid.com>
To: hoey@nrl-aic.arpa
Cc: common-lisp@sail.Stanford.EDU, mike@live-oak.lcs.mit.edu,
RWK@ai.ai.mit.edu, hilfingr@ucbvax.berkeley.edu,
CL.BOYER@r20.utexas.edu, KMP@stony-brook.scrc.symbolics.com
In-Reply-To: Dan Hoey's message of 12 Feb 1988 10:22:34 EST (Fri) <571677767/hoey@nrl-aic.arpa>
Subject: Package Odor
re: . . . You should know the names of all the symbols you import (including
all the symbols exported from packages you use), not only so you don't
get surprised about them being special, but so you don't accidentally
make them special when they shouldn't be. What the package system buys
you is letting this not be all the symbols in the world.
Very astute observation! I believe there's been a proposal to the cleanup
committee which would declare it to be "an error" for someone to redefine a
function in the LISP package. But Common Lisp doesn't even make it "an
error" to put all sorts of garbage into the LISP package (which everybody
*has* to use) and proclaim it INLINE and SPECIAL and all that jazz.
This problem is at once both the beauty of Lisp and its greatest weakness.
LISP has endured all these years because it is an "open system"; user code
-- in a very non-lexical way -- can muck around with the internals of:
Parsing [reader macros]
Compiling [ordinary macros, eval-when computations]
Loading [few, if any constraints, on cross-package reference]
Running [*print-base*, special variables, dynamic fn redefinition]
Interpretation
[ordinary macros, STEP, DEFADVICE, etc]
So it sounds like there is a need for listing all the assumptions that
keep a Common Lisp program sound --
What functions *should* not be redefined
What variables (and fns) *should* not be proclaimed in any way
What types shouldn't be overridden
What defstructs shouldn't be incompatibly redefined
What defstructs shouldn't be extended (via :include)
What package machinations should not be done
[e.g., Puting random external symbols in the LISP pacakge;
Putting symbols "owned" by other packages into KEYWORD;
EXPORTing symbols after a file using them has been compiled.]
. . . ??
The goal is not to make Lisp a strongly-typed language, or any other
"fascist beast", but to promulgate style guidelines which would enable
cooperating programs not to trash one another.
I believe that a reasonable set of such guidlines could be made for the
existing Common Lisp systems.
-- JonL --
∂13-Feb-88 1646 Common-Lisp-mailer Re: {Improved version} EXPORT-IMPORT and the other random commands
Received: from SPICE.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 13 Feb 88 16:46:27 PST
Date: 13 Feb 1988 19:31-EST
From: Jamie.Zawinski@spice.cs.cmu.edu (The Masked Avenger)
To: mike%acorn@oak.lcs.mit.edu
Cc: common-lisp@SAIL.STANFORD.EDU
Subject: Re: {Improved version} EXPORT-IMPORT and the other random commands
> My experience is that noone wants to qualify any names so what
> they do is carefully use every package that they've ever seen,
> not realizing that
>
> (let ((string "abcd"))
> ....)
>
> in their code is creating a spec-bind because they are using a package
> where string is a special.
>
> nuff said.
Not quite enough; I'd say that the blame for this particular lossage
falls squarely on the author of the USEd package, not on the person
USEing it. Anyone who would proclaim STRING special is a complete bogon.
If it's a global special variable, it should have *'s around it.
If it's a constant, it should either a) have a name less likely to
break the entire world, or b) be SHADOWed and not be EXPORTed.
If someone really wanted to have a global special or a constant called
STRING, (ick) then SHADOWing the symbol would solve (or at least make
clearer) the problem. If STRING was SHADOWed in the FOO package, and
also EXPORTed from FOO, and BAR tried to USE FOO, an error would be
signalled, because BAR was trying to inherit both FOO:STRING and
LISP:STRING.
I'm not at all sure what the "right" way to deal with packages is, but
I find that life is much easier if package-related activities are kept
to a minimum. If you have one package per application, then there are
few problems. It's when you try to interface your application with
someone else's that you get screwed.
Jamie
∂14-Feb-88 2147 Common-Lisp-mailer Package Odor
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 14 Feb 88 21:46:47 PST
Received: by labrea.Stanford.EDU; Sun, 14 Feb 88 21:47:05 PST
Received: from bhopal.lucid.com by edsel id AA26152g; Sun, 14 Feb 88 20:53:38 PST
Received: by bhopal id AA15077g; Sun, 14 Feb 88 20:58:42 PST
Date: Sun, 14 Feb 88 20:58:42 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8802150458.AA15077@bhopal.lucid.com>
To: Gumby@mcc.com
Cc: common-lisp@sail.Stanford.EDU, hoey@nrl-aic.arpa,
mike@live-oak.lcs.mit.edu, hilfingr@ucbvax.berkeley.edu,
CL.BOYER@r20.utexas.edu, KMP@stony-brook.scrc.symbolics.com,
RWK@ai.ai.mit.edu
In-Reply-To: David Vinayak Wallace's message of Sat, 13 Feb 88 01:59 CST <880213015956.2.GUMBY@THOTH.ACA.MCC.COM>
Subject: Package Odor
[Hi Gumby! long time no see. I'd heard that you were at MCC].
re: Now I think defpackage itself is not even close to the right thing; ...
Neither do I. At one time, I thought a defpackage was the answer to package
problems, but I've gotten "cold feet" about it after devling into it deeper.
The two main thorns I see are:
(1) It only works "as advertised" if there are *no* lisp primitives for
making changes to the package system [e.g., EXPORT, USE-PACKAGE, etc].
If you have these others, the DEFPACKAGE/SYSTEM is no surety at all;
in fact, it would be just one more headache to worry about when a
universally-recognized set of conventions-for-winning is established.
[consider the questions raised by Sandra Loosemore in her message of
Fri, 12 Feb 88 13:00:34 MST]. Ruling out primitives for the user to
make updates to packages at runtime seems to me to go very much against
the Lisp tradition; sounds more like the constraints of a statically
typed langugage.
(2) Unlike all other Lisp facilities, this one has to address the issue
of how to redefine a global structure. For example, if you have a
database file, and along comes a new-kid-on-the-block who says "Here
is the contents for that database file", then how do you resolve
the current contents, which many clients have already used and "cached"?
Do you flush the current contents entirely? Do you try to "unify" the
current and redefining contents, signalling errors if there is an
unresolvable request? Currently, CL definers fall into three
categories:
(i) Those like DEFUN which only update some slot of a symbol; they
do not attempt to merge the actions of the old function found
in that cell with the new definition. Lisp is well-accustomed
to the dynamic update of symbol slots; and some implementations
give you warnings when you do redefine.
(ii) Those like MAKE-PACKAGE which signal an error on any attempt
to redefine the name-to-package mapping [a global database]
(iii) Those like DEFTYPE and DEFSTRUCT which simply displace the
former definitions [the global database involved here is
the implementation-dependent one for type descriptors and
defstruct descriptors].
The CLOS specification tries to describe a "unification" algorithm for
class redefinition [i.e., which old methods to throw out and which to
retain, etc]. But I think such a think for packages is overly
complicated and prone to unforseen consequences, especially since it
doesn't really solve the "package problem".
I don't have an idea right now of just how many constraints are necessary
to fix the "package problem", but there certainly is room for disucssion.
For example, I might not want to accept the restriction that Mike Beckerle
proposed -- no user use of USE-PACKAGE -- even though his notion of a
style guide and better compiler specification looked good. There must be
other reasonable alternatives that don't sacrifice the inheritable nature
of CL's packages.
-- JonL --
∂15-Feb-88 1521 Common-Lisp-mailer Package odor
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Feb 88 15:20:58 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 344006; Mon 15-Feb-88 18:20:52 EST
Date: Mon, 15 Feb 88 18:20 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Package odor
To: mike%acorn@oak.lcs.mit.edu, Dan Hoey <hoey@NRL-AIC.ARPA>, Sandra J Loosemore <sandra%orion@cs.utah.edu>,
Jon L White <edsel!jonl@labrea.Stanford.EDU>, RWK@AI.AI.MIT.EDU, Gumby@mcc.com,
hilfingr%tully.Berkeley.EDU@UCBVAX.BERKELEY.EDU, CL.BOYER@R20.UTEXAS.EDU
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: The message of 11 Feb 88 19:26 EST from mike%acorn@oak.lcs.mit.edu,
<571677767/hoey@nrl-aic.arpa>,
<8802122000.AA14679@orion.utah.edu>,
<8802130612.AA13238@bhopal.lucid.com>,
<8802150458.AA15077@bhopal.lucid.com>
Message-ID: <19880215232057.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
In case anyone's been wondering why I, who supposedly know something
about packages, haven't said anything in this discussion, it's because
this doesn't seem to be any different from the same discussion ten years
ago at MIT and five years ago in the Common Lisp working group.
Here's the very brief encapsulated wisdom. It was ignored last time,
and will probably be ignored this time, but I'll send it out once anyway.
Packages are a way of controlling the mapping from names to symbols.
If what you're looking for is a way to control the mapping from symbols
to objects (and that is what you should be looking for), packages are
bound to disappoint you. Packages are useful for what they do, but not
for more. Better ideas do exist. The oldest published better idea I
know of is in SDC TM-2710/111/00, 7 January 1966 (from the LISP 2 effort,
unfortunately stillborn).
The only way to use packages that works reliably in the real world is to
set up the packages in advance and be very careful about making incremental
changes. The way that CLtL encourages you to use packages simply does not
work reliably for mere mortals. This is because of the early binding of
the mapping of names to symbols by the Lisp reader.
You can learn how to use packages effectively by studying how the
community that has been using them the longest does it.
∂15-Feb-88 2232 Common-Lisp-mailer Creepy Crawlers in the Package system
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Feb 88 22:32:42 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa10416; 16 Feb 88 1:27 EST
Received: from cs.umass.edu by RELAY.CS.NET id ax27248; 16 Feb 88 1:20 EST
Date: Mon, 15 Feb 88 15:06 EDT
From: ELIOT@cs.umass.edu
Subject: Creepy Crawlers in the Package system
To: Common-Lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"Common-Lisp@sail.stanford.edu"
Some of the comments I have read sound like things people
say who spend all of their time *implementing* Lisp and
none of their time *using* Lisp.
I have been (trying to) write programs using KnowledgeCraft
and Kee. You can be pretty sure that I am going to USE-PACKAGE
these system's packages. Each of them provides Hundreds of
additional functions that might get used. I am a pretty
fast typist, but I still don't plan to individually import
every symbol that I am going to use.
A further problem arose with the GRAPPLE system, which
is built on KnowledgeCraft. Its been a year and a half
since I was involved in that, but basically the system
really wants to have transitively exported symbols.
GRAPPLE is supposed to be something that another system
(in its package) would be layered on top of. That system
would (use-package 'grapple) but it would also have to use
all of the KnowldegCraft packages (5 or 6 of them).
There might have been some kludge with Grapple writing
code that called K.C. functions or whatever. I don't
remember exactly why this happened, but the non-transitive
nature of packages/exporting was a real pain.
I think this is actually the most important situation.
When using a large software package there are just too
many symbols around to be a purist.
Please add my vote to the list of those who think the
package system is something the cat dragged in from the
storm, but don't really know what to do about it.
Chris Eliot
∂18-Feb-88 1208 Common-Lisp-mailer Results of query regarding multiprocessor applications and simulators
Received: from hecuba.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 18 Feb 88 12:08:05 PST
Received: by hecuba.Berkeley.EDU (5.57/1.25)
id AA23112; Thu, 18 Feb 88 12:09:19 PST
Message-Id: <8802182009.AA23112@hecuba.Berkeley.EDU>
To: common-lisp@sail.stanford.edu
Subject: Results of query regarding multiprocessor applications and simulators
Date: Thu, 18 Feb 88 12:09:15 PST
From: Benjamin Zorn <zorn%hecuba.Berkeley.EDU@ginger.Berkeley.EDU>
More than a month ago I sent mail to the mailing list requesting
information about multiprocessor Lisp implementations, applications,
and simulators. Since then I have received mail from a number of
sources, and I'd like to summarize the mail I received here. I'll
briefly mention the work that's being done, mention a reference to
recent publications, and give an e-mail address for people who would
like more information.
Location: MIT
Contact: Robert Halstead, rrh@vx.lcs.mit.edu
Hardware: Concert multiprocessor (MIT research machine)
Language: Multilisp (described in TOPLAS, Oct. 1985)
Applications: a wide variety, ranging from circuit simulation to
speech recognition
Location: BBN Advanced Computers, Inc.
Contact: Seth Steinberg, sas@bfly-vax.bbn.com
Hardware: BBN Butterfly
Language: Butterfly Lisp, which started as an adaptation of CScheme,
but is progressing toward full Common Lisp compatibility (described in
AAAI-87). Multiprocessing primitives are quite close to those of Multilisp.
Applications: language recognition, object oriented multiprocessor
simulation, multiprocessor expert systems.
Location: Stanford Knowledge Systems Laboratory
Contact: Nakul Saraiya, saraiya@sumex-aim.stanford.edu
Simulator: CARE, a parameterizable architectural simulator for
multiprocessor systems that is focussed on their communications and
scheduling behavior (several recent Stanford tech reports describe
various aspects of the system).
Language: LAMINA, a basic language interface that allows application
code to be written in functional, object-oriented, or shared-variable
styles.
Applications: two report integration systems (AIRTRAC & ELINT) and a
PDE solver.
Location: Stanford
Contact: Joe Weening, jsw@sail.stanford.edu
Hardware: Alliant FX/8 multiprocessor
Language: Qlisp, described in the 1984 Lisp Conference
Applications: still preliminary, but working on symbolic algebra,
proof checking systems, and parallel OPS5.
Location: Nasa Ames
Contact: Bob Meier, MEIER%PLU@io.arc.nasa.gov
Language: Common Lisp with futures (description submitted to 1988
ICPP), implemented on Symbolics and VAX simulators.
Applications: multiprocessing expert system shell as part of the
Holmes project.
Location: UC Berkeley
Contact: Benjamin Zorn, zorn@ernie.berkeley.edu
Hardware: SPUR multiprocessor workstation (in preparation)
Language: SPUR Lisp (Common Lisp + Mailboxes + Processes + futures)
(description soon to be available as a UC Berkeley tech report)
Applications: limited to small programs due to the absence of actual
SPUR hardware.
I am aware of other multiprocessor Lisp implementations, most notably
ZLisp, the multiprocessor Lisp for the NYU ultracomputer; and *Lisp,
Lisp with data level parallelism for the Connection machine. I didn't
receive any information about multiprocessor applications on these
machines, so I haven't included them in this list.
One respondent, Tanaka Tomoyuki, was particularly interested in
gathering together a bibliography on parallel lisp systems and
applications. In particular, references to tech reports, which do not
appear in citation indexes, would be of special interest. If you have
lists of any such references, please send them to:
name: TANAKA Tomoyuki
institution: Tokyo Research Laboratory, IBM Japan
e-mail address: tanakat@jpntscvm.bitnet
(IBM VNET: TANAKAT at TRLVM1)
(Japan junet: tanakat@trla.ibmtrl.junet)
I am still interested in hearing about multiprocessor applications,
and will post an update to this list as I hear about additional work.
∂18-Feb-88 1400 Common-Lisp-mailer Heat and Howard Trickey
Received: from tully.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 18 Feb 88 14:00:23 PST
Received: by tully.Berkeley.EDU (5.57/1.25)
id AA10300; Thu, 18 Feb 88 14:01:38 PST
From: hilfingr%tully.Berkeley.EDU@ginger.Berkeley.EDU (Paul Hilfinger)
Message-Id: <8802182201.AA10300@tully.Berkeley.EDU>
To: common-lisp@sail.stanford.edu
Subject: Heat and Howard Trickey
Date: Thu, 18 Feb 88 14:01:35 PST
Even in the best of times, the night wind blowing in from the San
Francisco Bay can get a bit cold at times, and my workstation no
longer warms the blood as it used to. What I really need is a good
flame raging cheerfully at me from the screen.
With this in mind, have y'all seen Howard Trickey's article, "C++
Versus Lisp: A Case Study" in SIGPLAN Notices 23, 2 (Feb. 1988), pp.
9-18?
P. Hilfinger
∂19-Feb-88 0952 Common-Lisp-mailer Results of query regarding multiprocessor applications and simulators
Received: from NSS.Cs.Ucl.AC.UK (TUNNEL.CS.UCL.AC.UK) by SAIL.Stanford.EDU with TCP; 19 Feb 88 09:51:47 PST
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa09088; 19 Feb 88 17:38 GMT
Received: from xenakis by mordell.maths.bath.AC.UK id aa28204;
19 Feb 88 17:36 GMT
To: zorn <@ginger.berkeley.edu:zorn@hecuba.berkeley.edu>
CC: common-lisp@sail.stanford.edu
In-reply-to: Benjamin Zorn's message of Thu, 18 Feb 88 12:09:15 PST <8802182009.AA23112@hecuba.Berkeley.EDU>
Subject: Results of query regarding multiprocessor applications and simulators
Date: Fri, 19 Feb 88 17:38:12 GMT
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
I am a little confused. I thought you asked for parallel Common Lisp
work, but your collective message omits the word "Common". Which did
you ask for? And which did you want?
==John ff
∂24-Feb-88 1803 Common-Lisp-mailer Heat and Howard Trickey
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 24 Feb 88 18:03:27 PST
Date: Wed, 24 Feb 88 19:46:14 EST
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: Heat and Howard Trickey
To: hilfingr%tully.Berkeley.EDU@GINGER.BERKELEY.EDU
cc: common-lisp@SAIL.STANFORD.EDU
In-reply-to: Msg of Thu 18 Feb 88 14:01:35 PST from hilfingr%tully.Berkeley.EDU at ginger.Berkeley.EDU (Paul Hilfinger)
Message-ID: <331493.880224.RWK@AI.AI.MIT.EDU>
Barton warned me about you!
I haven't seen the article, but the TITLE is enough to make me flame!
I mean, any language that would name itself after one of C's more
cryptic "character-saving" constructs is not something you'd need to
bother comparing to Lisp, let alone write a paper on it!
OK, I guess I'll have to locate the article & get more fuel. Can't
let you Californians get chilled, now can we?
∂25-Feb-88 1439 Common-Lisp-mailer Heat and Howard Trickey
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 25 Feb 88 14:39:14 PST
Return-Path: <gls@Think.COM>
Received: from kali.think.com by Think.COM; Thu, 25 Feb 88 17:38:38 EST
Received: by kali.think.com; Thu, 25 Feb 88 17:38:34 EST
Date: Thu, 25 Feb 88 17:38:34 EST
From: gls@Think.COM
Message-Id: <8802252238.AA04941@kali.think.com>
To: RWK@ai.ai.mit.edu
Cc: hilfingr%tully.Berkeley.EDU@ginger.berkeley.edu,
common-lisp@sail.stanford.edu
In-Reply-To: "Robert W. Kerns"'s message of Wed, 24 Feb 88 19:46:14 EST <331493.880224.RWK@AI.AI.MIT.EDU>
Subject: Heat and Howard Trickey
Date: Wed, 24 Feb 88 19:46:14 EST
From: "Robert W. Kerns" <RWK@ai.ai.mit.edu>
Barton warned me about you!
I haven't seen the article, but the TITLE is enough to make me flame!
I mean, any language that would name itself after one of C's more
cryptic "character-saving" constructs is not something you'd need to
bother comparing to Lisp, let alone write a paper on it!
C purists (I count myself one), who know the difference between prefix ++
and postfix ++, observe that the name C++ may be loosely paraphrased as
"improve C, then throw the result away and use the old language".
--Quux
∂26-Feb-88 1235 Common-Lisp-mailer package question
Received: from rutgers.edu by SAIL.Stanford.EDU with TCP; 26 Feb 88 12:34:50 PST
Received: by rutgers.edu (5.54/1.15) with UUCP
id AA13305; Fri, 26 Feb 88 15:16:18 EST
Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424)
id AA24602; Wed, 24 Feb 88 19:17:29 PST
Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424)
id AA25276; Wed, 24 Feb 88 19:20:03 PST
Date: 24 Feb 1988 19:19-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Subject: package question
To: common-lisp@sail.stanford.edu@rutgers.edu
Message-Id: <572757552/bein@pyrnova>
Suppose we have the following:
* *PACKAGE*
#<A package named USER> ;
* (SETQ P 'LISP::NEW-SYMBOL)
LISP::NEW-SYMBOL ;
* (IMPORT P *PACKAGE*)
T ;
* P
NEW-SYMBOL ;
* (UNINTERN P (SYMBOL-PACKAGE P))
T ;
* P
#:NEW-SYMBOL
* (FIND-SYMBOL "NEW-SYMBOL" *PACKAGE*)
#:NEW-SYMBOL ;
:INTERNAL ;
* (EQ * P)
T ;
* 'NEW-SYMBOL
#:NEW-SYMBOL
* (EQ * P)
T ;
We have an inconsistency here since printing does not equal reading.
Should the reader give the symbol a home if it does not have one?
Or should the printer be noticing that a symbol with no home is
in fact accessible in the current package (and not prefix with #:)?
* (IMPORT P *PACKAGE*)
T ;
* P
NEW-SYMBOL ;
* 'NEW-SYMBOL
NEW-SYMBOL ;
* (EQ * P)
T ;
Is IMPORT doing the right thing by giving the symbol a home package
if it does not have one?
--David
∂26-Feb-88 1237 Common-Lisp-mailer the KEYWORD package ...
Received: from rutgers.edu by SAIL.Stanford.EDU with TCP; 26 Feb 88 12:36:46 PST
Received: by rutgers.edu (5.54/1.15) with UUCP
id AA13340; Fri, 26 Feb 88 15:17:42 EST
Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424)
id AA24647; Wed, 24 Feb 88 19:19:13 PST
Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424)
id AA25304; Wed, 24 Feb 88 19:21:47 PST
Date: 24 Feb 1988 19:20-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Subject: the KEYWORD package ...
To: common-lisp@sail.stanford.edu@rutgers.edu
Message-Id: <572757648/bein@pyrnova>
Suppose we have a symbol which has no home package which is going
to be imported into the keyword package using one of IMPORT,SHADOW,
or SHADOWING-IMPORT. Should those functions "keyword-ize" the
symbol ala INTERN, i.e. should the value of the symbol be set
to itself? While on the subject, should the keyword package be
allowed to use (or be used by) other packages?
I am leaning in favor of:
(1) Anytime a symbol's home package is set to the keyword package,
the symbol is keywordized destroying any previous value.
(2) It should be an error for the keyword package to use (or be used by)
another package.
(3) It should be an error to import a symbol into the keyword package
which already has another home package.
--David
∂26-Feb-88 1400 Common-Lisp-mailer the KEYWORD package ...
Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by SAIL.Stanford.EDU with TCP; 26 Feb 88 14:00:18 PST
Received: from SWAN.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 207635; Fri 26-Feb-88 16:59:28 EST
Date: Fri, 26 Feb 88 16:58 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Subject: the KEYWORD package ...
To: David Bein <pyrnj!pyramid!bein@rutgers.edu>, common-lisp@sail.stanford.edu
In-Reply-To: <572757648/bein@pyrnova>
Message-ID: <19880226215805.5.DCP@SWAN.SCRC.Symbolics.COM>
Date: 24 Feb 1988 19:20-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
(1) Anytime a symbol's home package is set to the keyword package,
the symbol is keywordized destroying any previous value.
I think it should be an error to import something into the keyword
package. Yes, this makes the keyword package more magic than it already
is. That's perfectly OK with me unless I hear a good answer to this
question:
What programming model are you using that suggests you want to do
something like this?
(2) It should be an error for the keyword package to use (or be used by)
another package.
I agree.
(3) It should be an error to import a symbol into the keyword package
which already has another home package.
See (1).
∂26-Feb-88 1445 Common-Lisp-mailer package question
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 26 Feb 88 14:45:37 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 26 Feb 88 17:45:02 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 26 Feb 88 17:44:58 EST
Date: Fri, 26 Feb 88 17:46 EST
From: Barry Margolin <barmar@Think.COM>
Subject: package question
To: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <572757552/bein@pyrnova>
Message-Id: <19880226224604.9.BARMAR@OCCAM.THINK.COM>
Date: 24 Feb 1988 19:19-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
[Why do
Suppose we have the following:
* *PACKAGE*
#<A package named USER> ;
* (SETQ P 'LISP::NEW-SYMBOL)
LISP::NEW-SYMBOL ;
* (IMPORT P *PACKAGE*)
T ;
* P
NEW-SYMBOL ;
* (UNINTERN P (SYMBOL-PACKAGE P))
T ;
* P
#:NEW-SYMBOL
* (FIND-SYMBOL "NEW-SYMBOL" *PACKAGE*)
#:NEW-SYMBOL ;
:INTERNAL ;
* (EQ * P)
T ;
* 'NEW-SYMBOL
#:NEW-SYMBOL
* (EQ * P)
T ;
We have an inconsistency here since printing does not equal reading.
Should the reader give the symbol a home if it does not have one?
Or should the printer be noticing that a symbol with no home is
in fact accessible in the current package (and not prefix with #:)?
Print-read consistency is only guaranteed for interned symbols [CLtL
p.173]; a symbol is uninterned if it has no home package, whether or not
it is accessible in any package. And on p.176, CLtL says that #:BAR
syntax is used "when the symbol BAR is uninterned (has no home package),
even in the pathological case that BAR is uninterned but nevertheless
somehow accessible in the current package." You have created such a
pathological case. And the description of UNINTERN on p.185 says that
it should be used with caution because it "changes the state of the
package system in such a way that the consistency rules do not hold
across the change."
* (IMPORT P *PACKAGE*)
T ;
* P
NEW-SYMBOL ;
* 'NEW-SYMBOL
NEW-SYMBOL ;
* (EQ * P)
T ;
Is IMPORT doing the right thing by giving the symbol a home package
if it does not have one?
This issue was addressed by the X3J13 Cleanup subcommittee, in issue
IMPORT-SETF-SYMBOL-PACKAGE. A decision about this was made last June;
unfortunately, I don't recall specifically what the decision was, but
I'll wager we made the above valid.
barmar
∂27-Feb-88 1036 Common-Lisp-mailer Lisp Innards Wanted!
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 27 Feb 88 10:36:42 PST
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA02452; Sat, 27 Feb 88 11:37:17 MST
Date: Sat, 27 Feb 88 11:37:17 MST
From: shebs@cs.utah.edu (Stanley Shebs)
Message-Id: <8802271837.AA02452@cs.utah.edu>
To: common-lisp@sail.stanford.edu
Subject: Lisp Innards Wanted!
[Apologies to those who have seen this already, how could I have forgotten
the COMMON-LISP list!]
As part of my dissertation, I've been collecting info on the internal data
representations of various Lisp systems. Lisp here is broadly defined as
any language ultimately based on Lisp 1.5, and includes Scheme. What I'm
looking for is the grungiest of machine-level details on the layout of cons
cells, type discrimination schemes, memory organization, and storage recovery.
Moon's description of the Symbolics architecture in the January 87 Computer is
an excellent example, especially the pictures. Not every single detail is
needed; just those that required conscious decisions by an implementor. (For
instance, if arrays are tagged with a 0 to avoid masking, that is interesting,
but if it was only because "array" is the first type name in the dictionary,
that is not interesting.) Implementations embedded in other Lisps (Scheme 84,
PCLS) are not of interest, but this does not exclude those written in other
high-level languages (as can be seen from the list below).
At present I have reasonably complete descriptions of the following systems,
mostly derived from published material, manuals, or source code:
7090 Lisp 1.5
M-460 Lisp
Q-32 Lisp
PDP-1 Lisp
Lisp 1.6
UCI Lisp
MacLISP (PDP-10, Multics)
Interlisp (VAX, PDP-10, -D)
LISP-11
Cambridge LISP (IBM)
Zetalisp
Franz Lisp
PSL
NIL
Spice Lisp
S-1 Lisp
Franz Extended Common Lisp
T
MIT Scheme
PC Scheme
Scheme-48
Lisp F3
XLISP
VT-LISP
Kyoto Common Lisp
VLISP
LeLisp
Multilisp
I have only sketchy or no data on the following systems:
muLisp
TLC-Lisp
Cambridge Lisp (ST)
Apollo Domain Lisp (the PSL deriv)
Rutgers Lisp-20
Rutgers DEC-20 Common Lisp
Golden Common Lisp
HP Common Lisp
VAXLisp
Pyramid Common Lisp
Lucid Lisp
There are certainly others I've forgotten or simply don't know about - any
info on these is quite welcome! Long-ago implementations are just as worth
knowing about as more recent ones.
Details received will go into my dissertation, and possibly into a separate
tech report; any contributor who wants one will get a copy when this work is
completed, perhaps in three months or so. The dissertation itself is about
Lisp data structure design in general, and how it might be formalized.
Of course, all contributions will be properly credited, not to mention
greatly appreciated!
stan shebs
shebs@cs.utah.edu
uunet!utah-cs!shebs
∂28-Feb-88 0116 Common-Lisp-mailer package question
Received: from rutgers.edu by SAIL.Stanford.EDU with TCP; 28 Feb 88 01:16:11 PST
Received: by rutgers.edu (5.54/1.15)
id AA12121; Sun, 28 Feb 88 03:58:00 EST
Received: ID <RAM@C.CS.CMU.EDU.#Internet>; Sun 28 Feb 88 03:21:41-EST
Date: Sat, 27 Feb 1988 20:39 EST
Message-Id: <RAM.12378195698.BABYL@>
Sender: RAM@λλ
From: Ram@c.cs.cmu.edu
To: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Cc: common-lisp@sail.stanford.edu
Subject: package question
In-Reply-To: Msg of 24 Feb 1988 22:19-EST from David Bein <pyrnj!pyramid!bein at rutgers.edu>
Print-read consistency isn't maintained when you use "dangerous"
functions such as IMPORT and UNINTERN. See page 173. I understand
that it is non-intuitive that an "uninterned" symbol can be
accessible, but this is consistent with the other generally
non-intuitive behavior of the package system.
One of the most important things you must realize before you can
understand what the package system really does (as opposed to what you
want it to do) is to realize that symbols don't "belong" to any
package, and that the home package means nothing except when printing,
and not much even then.
Rob
∂28-Feb-88 0618 Common-Lisp-mailer package question
Received: from rutgers.edu by SAIL.Stanford.EDU with TCP; 28 Feb 88 06:18:12 PST
Received: by rutgers.edu (5.54/1.15)
id AA17994; Sun, 28 Feb 88 08:33:48 EST
Received: ID <RAM@C.CS.CMU.EDU.#Internet>; Sun 28 Feb 88 08:02:51-EST
Date: Sat, 27 Feb 1988 20:55 EST
Message-Id: <RAM.12378198598.BABYL@>
Sender: RAM@λλ
From: Ram@c.cs.cmu.edu
To: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Cc: common-lisp@sail.stanford.edu
Subject: package question
In-Reply-To: Msg of 24 Feb 1988 22:19-EST from David Bein <pyrnj!pyramid!bein at rutgers.edu>
Date: Wednesday, 24 February 1988 22:19-EST
From: David Bein <pyrnj!pyramid!bein at rutgers.edu>
Re: package question
[...]
Is IMPORT doing the right thing by giving the symbol a home package
if it does not have one?
I believe there is nothing in CLTL that suggests this, but at one
point a while back there was a discussion of this, and the consensus
seemed to be that IMPORT should set the home package when it was null.
This was way before the ANSII standardization processes started. (CMU
Lisp also has this behavior.)
Rob
∂29-Feb-88 0408 Common-Lisp-mailer Re: Lisp Innards Wanted!
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 04:08:43 PST
Received: from Burger.ms by ArpaGateway.ms ; 29 FEB 88 04:07:49 PST
Sender: "Larry_Masinter.PARC"@Xerox.COM
Date: 29 Feb 88 04:06:59 PST (Monday)
Subject: Re: Lisp Innards Wanted!
From: MASINTER.PARC@Xerox.COM
To: shebs@cs.utah.EDU
cc: common-lisp@sail.stanford.EDU
In-Reply-to: shebs%cs.utah:EDU's message of Saturday, February 27, 1988 11:09 am
Reply-to: MASINTER.PARC@Xerox.COM
Message-ID: <880229-040749-1061@Xerox>
I'm willing to review your dissertation for technical accuracy, at least about the
Lisp implementations that I'm familiar with.
Larry Masinter
Xerox PARC
3333 Coyote Hill Road
Palo Alto, cA 94304
∂29-Feb-88 0634 Common-Lisp-mailer Order of arguments to sequence :TEST functions
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 29 Feb 88 06:34:50 PST
Received: from SWAN.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 232161; Mon 29-Feb-88 09:34:48 EST
Date: Mon, 29 Feb 88 09:34 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Subject: Order of arguments to sequence :TEST functions
To: common-lisp@sail.stanford.edu
Message-ID: <19880229143424.3.DCP@SWAN.SCRC.Symbolics.COM>
CLtL page 247 says
... (funcall testfn item (keyfn x)) ...
I'm curious to know why this order was chosen instead of
... (funcall testfn (keyfn x) item) ...
When I hand code predicates, I usually put the more variable thing first
and the more constant thing second, as in
(defun poor-mans-position (array frob)
(dotimes (index (length array))
(when (eql (aref array index) frob)
(return index))))
The (Symbolics implementation) of xCASE macros are similar, in that the
keyform is the more variable and the clauses are the more constant, and
it is roughly (eql keyform clause) or (member keyform clause) as
appropriate. Since EQL is commutative, this doesn't matter much.
The xTYPECASE macros are somewhat similar: they keyform is the more
variable and the type is more contant. Of course, this is largely based
on the order of arguments to TYPEP. Still, there is a potential
analogy.
Generally, I view "is it XYZ" to be (test it XYZ). This generally holds
except for the sequence functions, such as FIND, where I view XYZ being
the item and "it" being the element of the sequence.
What I was trying to do was use FIND to find an item of a certain type,
as in
(find type sequence :test #'typep)
but the order of the arguments as defined in CLtL is backwards. The
closest I could get was
(find type sequence :key #'type-of :test-not #'subtypep)
with the knowledge that there was no exact match (it was a flavor
mixin).
Yes, I know I can use find-if, and that's what I'm really doing. Was
there a reason for the ordering choice? Does anybody depend on it, or
know of somebody that does? Is there any chance of CLtL'89 reversing
it (and documenting the reason in the text)?
∂29-Feb-88 0757 Common-Lisp-mailer Order of arguments to sequence :TEST functions
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 29 Feb 88 07:57:00 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU.#Internet>; Mon 29 Feb 88 10:57:07-EST
Date: Mon, 29 Feb 1988 10:57 EST
Message-ID: <FAHLMAN.12378613904.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: common-lisp@SAIL.STANFORD.EDU
Subject: Order of arguments to sequence :TEST functions
In-reply-to: Msg of 29 Feb 1988 09:34-EST from David C. Plummer <DCP at QUABBIN.SCRC.Symbolics.COM>
I think that the definition on page 247 is what seemed intuitive to the
designers at the time, probably reflecting some pre-existing practice in
some system or other. Your view of the proper order is an interesting
one, but doesn't seem to be universal, and nobody argued this point of
view at the time. My intuition tends to go in the opposite direction:
typep seems backwards to me, because I view the function and type
argument as being a sort of composite function that is then applied to
the thing being investigated. I agree that it is unfortunate that typep
and the :test keyword don't match, but as you point out there are ways
around this.
Yes, lots of code would have to be changed (in a trivial way) if we
switched this around now. I think that an incompatible change like this
has no chance of passing if the reason is just someone's view that the
order of arguments would be more intuitive if switched around.
-- Scott
∂29-Feb-88 0935 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 29 Feb 88 09:35:17 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 29 Feb 88 12:35-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 82575; 29 Feb 88 12:31:53-EST
Received: from PINK-FLOYD.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 95234; Mon 29-Feb-88 11:31:43-EST
Date: Mon, 29 Feb 1988 11:27 EST
From: Randy%acorn@oak.lcs.mit.edu
To: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Subject: [Order of arguments to sequence :TEST functions]
Cc: Randy, common-lisp@sail.stanford.edu
> Date: Mon, 29 Feb 88 09:34 EST
> From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
> Subject: Order of arguments to sequence :TEST functions
> To: common-lisp@sail.stanford.edu
>
> CLtL page 247 says
> ... (funcall testfn item (keyfn x)) ...
> I'm curious to know why this order was chosen instead of
> ... (funcall testfn (keyfn x) item) ...
> ...
> Yes, I know I can use find-if, and that's what I'm really doing. Was
> there a reason for the ordering choice? Does anybody depend on it, or
> know of somebody that does? Is there any chance of CLtL'89 reversing
> it (and documenting the reason in the text)?
It seems that anyone who does
(FIND number list-of-number :test #'<)
is depending on the order of the arguments to the test. I don't
know for sure if anyone depends on this, but it doesn't seem like
a particularly contorted example. There are a fair number of
non-commutative predicates.
Random
∂29-Feb-88 1003 Common-Lisp-mailer Re: package question
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:03:11 PST
Date: 29 Feb 1988 12:58-EST
Sender: NGALL@G.BBN.COM
Subject: Re: package question
From: NGALL@G.BBN.COM
To: barmar@THINK.COM
Cc: pyrnj!pyramid!bein@RUTGERS.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]29-Feb-88 12:58:14.NGALL>
In-Reply-To: <19880226224604.9.BARMAR@OCCAM.THINK.COM>
Date: Fri, 26 Feb 88 17:46 EST
From: Barry Margolin <barmar@Think.COM>
... And on p.176, CLtL says that #:BAR
syntax is used "when the symbol BAR is uninterned (has no home package),
even in the pathological case that BAR is uninterned but nevertheless
somehow accessible in the current package."
The statement on pg. 176 should be repeated on pg. 367 where it talks
about how to print a symbol. Currently, in reading pg. 367 in
isolation, one is left confused as to how to print an uninterned
symbol that is accesible in the current package.
-- Nick
∂29-Feb-88 1025 Common-Lisp-mailer Re: package question
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:03:11 PST
Date: 29 Feb 1988 12:58-EST
Sender: NGALL@G.BBN.COM
Subject: Re: package question
From: NGALL@G.BBN.COM
To: barmar@THINK.COM
Cc: pyrnj!pyramid!bein@RUTGERS.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]29-Feb-88 12:58:14.NGALL>
In-Reply-To: <19880226224604.9.BARMAR@OCCAM.THINK.COM>
Date: Fri, 26 Feb 88 17:46 EST
From: Barry Margolin <barmar@Think.COM>
... And on p.176, CLtL says that #:BAR
syntax is used "when the symbol BAR is uninterned (has no home package),
even in the pathological case that BAR is uninterned but nevertheless
somehow accessible in the current package."
The statement on pg. 176 should be repeated on pg. 367 where it talks
about how to print a symbol. Currently, in reading pg. 367 in
isolation, one is left confused as to how to print an uninterned
symbol that is accesible in the current package.
-- Nick
∂29-Feb-88 1047 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:47:13 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 29 Feb 88 13:45:54 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 29 Feb 88 13:45:49 EST
Date: Mon, 29 Feb 88 13:45 EST
From: Barry Margolin <barmar@Think.COM>
Subject: [Order of arguments to sequence :TEST functions]
To: Randy%acorn@live-oak.lcs.mit.edu
Cc: David C. Plummer <DCP@quabbin.scrc.symbolics.com>, Randy@sail.stanford.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <8802291736.AA16958@Think.COM>
Message-Id: <19880229184541.0.BARMAR@OCCAM.THINK.COM>
Date: Mon, 29 Feb 1988 11:27 EST
From: Randy%acorn@LIVE-OAK.LCS.MIT.EDU
It seems that anyone who does
(FIND number list-of-number :test #'<)
is depending on the order of the arguments to the test. I don't
know for sure if anyone depends on this, but it doesn't seem like
a particularly contorted example. There are a fair number of
non-commutative predicates.
This example reminds me of what I think is the reason for the particular
order chosen. I think the order of arguments to the test function is
always supposed to be the same as the order of arguments to the sequence
function, for ease of remembering.
barmar
∂29-Feb-88 1050 Common-Lisp-mailer Re: Order of arguments to sequence :TEST functions
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:50:27 PST
Date: 29 Feb 1988 13:49-EST
Sender: NGALL@G.BBN.COM
Subject: Re: Order of arguments to sequence :TEST functions
From: NGALL@G.BBN.COM
To: DCP@SCRC-QUABBIN.ARPA
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]29-Feb-88 13:49:03.NGALL>
In-Reply-To: <19880229143424.3.DCP@SWAN.SCRC.Symbolics.COM>
Date: Mon, 29 Feb 88 09:34 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
CLtL page 247 says
... (funcall testfn item (keyfn x)) ...
I'm curious to know why this order was chosen instead of
... (funcall testfn (keyfn x) item) ...
My personal theory is that the order of the arguments to the TESTFN is
the same as their order in the `surface' call, i.e., in most (all?) of
the sequence functions, the ITEM appears before the sequence (and
therefore before each element X of the sequence). This theory makes
it easy for me to remember the order of arguments to the TESTFN (so I
would hate to see the order changed).
-- Nick
∂29-Feb-88 1051 Common-Lisp-mailer Order of arguments to sequence :TEST functions
Received: from VALLECITO.SCRC.Symbolics.COM (SCRC-VALLECITO.ARPA) by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:51:16 PST
Received: from SWAN.SCRC.Symbolics.COM by VALLECITO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 208100; Mon 29-Feb-88 13:52:22 EST
Date: Mon, 29 Feb 88 13:50 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Subject: Order of arguments to sequence :TEST functions
To: Scott E. Fahlman <Fahlman@C.CS.CMU.EDU>, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <FAHLMAN.12378613904.BABYL@C.CS.CMU.EDU>
Message-ID: <19880229185047.6.DCP@SWAN.SCRC.Symbolics.COM>
Date: Mon, 29 Feb 1988 10:57 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Yes, lots of code would have to be changed (in a trivial way) if we
switched this around now.
I can believe you are right, but here's my reason why I think the amount
of change could be small: The change only affects non-commutative
predicates. Most of the predicates I have used and that I have seen are
commutative, basically EQ, EQL, EQUAL and /=.
I think that an incompatible change like this
has no chance of passing if the reason is just someone's view that the
order of arguments would be more intuitive if switched around.
Here's a quick test/poll. Without using the -IF or -IF-NOT functions,
- Remove all elements of a sequence which are less than 3.
- Find the first element of a sequence which is more than 3.
My "intuition" for coding this gives the wrong answers.
I know this doesn't show anything about language design.
∂29-Feb-88 1056 Common-Lisp-mailer Order of arguments to sequence :TEST functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Feb 88 10:55:56 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 352865; Mon 29-Feb-88 13:56:05 EST
Date: Mon, 29 Feb 88 13:55 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Order of arguments to sequence :TEST functions
To: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880229143424.3.DCP@SWAN.SCRC.Symbolics.COM>
Message-ID: <19880229185550.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 29 Feb 88 09:34 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
CLtL page 247 says
... (funcall testfn item (keyfn x)) ...
I'm curious to know why this order was chosen instead of
... (funcall testfn (keyfn x) item) ...
The design rationale is given just a few lines lower on the same
page. The order of arguments to the testfn is kept consistent with
the order of arguments to the sequence function in question.
Was there a reason for the ordering choice? Does anybody depend on it, or
know of somebody that does? Is there any chance of CLtL'89 reversing
it (and documenting the reason in the text)?
Yes. Yes. I hope not. Changing the order of arguments to something, in
a way so that the incompatibility cannot be mechanically detected and
warned about or assisted with, is the worst kind of incompatible change
from a user point of view.
What I was trying to do was use FIND to find an item of a certain type,
as in
(find type sequence :test #'typep)
but the order of the arguments as defined in CLtL is backwards.
Looks like a job for LAMBDA.
∂29-Feb-88 1120 Common-Lisp-mailer Re: the KEYWORD package ...
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 11:20:45 PST
Date: 29 Feb 1988 14:15-EST
Sender: NGALL@G.BBN.COM
Subject: Re: the KEYWORD package ...
From: NGALL@G.BBN.COM
To: pyrnj!pyramid!bein@RUTGERS.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]29-Feb-88 14:15:37.NGALL>
In-Reply-To: <572757648/bein@pyrnova>
Date: 24 Feb 1988 19:20-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Suppose we have a symbol which has no home package which is going
to be imported into the keyword package using one of IMPORT,SHADOW,
or SHADOWING-IMPORT. Should those functions "keyword-ize" the
symbol ala INTERN, i.e. should the value of the symbol be set
to itself?
Cf. pg 175: "The KEYWORD package is treated specially in that whenever a symbol
is added to the KEYWORD package the symbol is always made external; the symbol
is also automatically declared to be a constant (see DEFCONSTANT) and made to
have itself as its value."
I interpret the word `added' as encompassing INTERN, IMPORT, etc., so I would
say that the answer to your question is `yes'.
While on the subject, should the keyword package be
allowed to use (or be used by) other packages?
Cf. pg 187: "It is an error to try to use the KEYWORD package."
I don't see any problem with having the KEYWORD package use another package
(I don't see much point to it either). Do you?
I am leaning in favor of:
(1) Anytime a symbol's home package is set to the keyword package,
the symbol is keywordized destroying any previous value.
Since one can never directly `set' the home package of a symbol, I don't think
it is clear to couch a rule in that way. How about, "Anytime a symbol is made
present in the KEYWORD package, the symbol is `keywordized'..." This basically
rephrases pg 175.
(2) It should be an error for the keyword package to use (or be used by)
another package.
Why should it be an error for the keyword package to use another package?
(3) It should be an error to import a symbol into the keyword package
which already has another home package.
Why?
-- Nick
∂29-Feb-88 1208 Common-Lisp-mailer Order of arguments to sequence :TEST functions
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 12:05:50 PST
Return-Path: <gls@Think.COM>
Received: from kali.think.com by Think.COM; Mon, 29 Feb 88 15:04:48 EST
Received: by kali.think.com; Mon, 29 Feb 88 15:04:44 EST
Date: Mon, 29 Feb 88 15:04:44 EST
From: gls@Think.COM
Message-Id: <8802292004.AA10886@kali.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: DCP@quabbin.scrc.symbolics.com, common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Mon, 29 Feb 88 13:55 EST <19880229185550.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: Order of arguments to sequence :TEST functions
Date: Mon, 29 Feb 88 13:55 EST
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Date: Mon, 29 Feb 88 09:34 EST
From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
CLtL page 247 says
... (funcall testfn item (keyfn x)) ...
I'm curious to know why this order was chosen instead of
... (funcall testfn (keyfn x) item) ...
The design rationale is given just a few lines lower on the same
page. The order of arguments to the testfn is kept consistent with
the order of arguments to the sequence function in question.
The moral is: When in doubt...
...
What I was trying to do was use FIND to find an item of a certain type,
as in
(find type sequence :test #'typep)
but the order of the arguments as defined in CLtL is backwards.
Looks like a job for LAMBDA.
Or, for a general solution, try the C combinator:
(defun C (fn) #'(lambda (x y) (funcall fn y x)))
(find type sequence :test (C #'typep))
(find 3 numlist :text (C #'<)) ;find something less than 3
--Guy
∂29-Feb-88 1359 Common-Lisp-mailer Re: Order of arguments to sequence :TEST functions
Received: from cayuga.cs.rochester.edu (CS.ROCHESTER.EDU) by SAIL.Stanford.EDU with TCP; 29 Feb 88 13:59:37 PST
Received: by cayuga.cs.rochester.edu (5.52/h) id AA01879; Mon, 29 Feb 88 16:58:57 EST
Received: from loopback by lesath.cs.rochester.edu (3.2/h) id AA06946; Mon, 29 Feb 88 16:58:45 EST
Message-Id: <8802292158.AA06946@lesath.cs.rochester.edu>
To: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
Cc: common-lisp@SAIL.STANFORD.EDU
Subject: Re: Order of arguments to sequence :TEST functions
In-Reply-To: Your message of Mon, 29 Feb 88 13:50:00 -0500.
<19880229185047.6.DCP@SWAN.SCRC.Symbolics.COM>
Date: Mon, 29 Feb 88 16:58:40 -0500
From: quiroz@cs.rochester.edu
| Here's a quick test/poll. Without using the -IF or -IF-NOT functions,
| - Remove all elements of a sequence which are less than 3.
| - Find the first element of a sequence which is more than 3.
| My "intuition" for coding this gives the wrong answers.
| I know this doesn't show anything about language design.
Counterquestion: Why is it so important to do this `[w]ithout using
the -IF or -IF-NOT functions'? My first reaction is
(remove-if #'(lambda (elt) (< elt 3)) seq)
Cesar Quiroz
PS. "`Straightedge and Compass' is no more powerful than `Compass
alone'" [Mascheroni? Steiner? Both? Sigh, I don't remember anymore].
Interesting, but both alternatives are much less useful than a
decent plotter. :-)
∂29-Feb-88 1646 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 29 Feb 88 16:46:00 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 29 Feb 88 19:46-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 82653; 29 Feb 88 19:44:49-EST
Received: from PINK-FLOYD.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 95271; Mon 29-Feb-88 17:56:40-EST
Date: Mon, 29 Feb 1988 17:52 EST
From: Randy%acorn@oak.lcs.mit.edu
To: gls@Think.COM
Subject: [Order of arguments to sequence :TEST functions]
Cc: Randy, DCP@quabbin.scrc.symbolics.com, common-lisp@sail.stanford.edu, Moon@stony-brook.scrc.symbolics.com
> Return-Path: <gls@Think.COM>
> Date: Mon, 29 Feb 88 15:04:44 EST
> From: gls@Think.COM
> To: Moon@stony-brook.scrc.symbolics.com
> Cc: DCP@quabbin.scrc.symbolics.com, common-lisp@sail.stanford.edu
> In-Reply-To: David A. Moon's message of Mon, 29 Feb 88 13:55 EST <19880229185550.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
> Subject: Order of arguments to sequence :TEST functions
> .....
> (find 3 numlist :text (C #'<)) ;find something less than 3
Is that the recently proposed :TEXT keyword, which tells the system
what to print if it doesn't find anything?
How about a new keyword for all the generix which take :TEST, called
:REVERSE-TEST. On certain machines, this could be implemented more
efficiently that using LAMBDA
;-)
Random
∂29-Feb-88 1853 Common-Lisp-mailer [Order of arguments to sequence :TEST functions]
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 29 Feb 88 18:53:45 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 29 Feb 88 21:54-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 82668; 29 Feb 88 21:50:52-EST
Received: from LEIPZIG.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 95277; Mon 29-Feb-88 21:31:24-EST
Date: Mon, 29 Feb 1988 21:32 EST
From: RpK%acorn@oak.lcs.mit.edu
Subject: [Order of arguments to sequence :TEST functions]
Cc: common-lisp@sail.stanford.edu
> Date: Mon, 29 Feb 88 09:34 EST
> From: David C. Plummer <DCP@QUABBIN.SCRC.Symbolics.COM>
> Subject: Order of arguments to sequence :TEST functions
> To: common-lisp@sail.stanford.edu
>
> CLtL page 247 says
> ... (funcall testfn item (keyfn x)) ...
> I'm curious to know why this order was chosen instead of
> ... (funcall testfn (keyfn x) item) ...
Well, one nice property about this is that
(find-if pred seq ...)
is equivalent to
(find pred seq :test #'funcall ...)
∂29-Feb-88 2111 Common-Lisp-mailer the KEYWORD package USEing another package
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 29 Feb 88 21:11:18 PST
Received: from THOTH.ACA.MCC.COM by MCC.COM with TCP; Mon 29 Feb 88 23:11:33-CST
Date: Mon, 29 Feb 88 23:08 CST
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: the KEYWORD package USEing another package
To: NGALL@G.BBN.COM
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM]29-Feb-88 14:15:37.NGALL>
Message-ID: <880229230848.2.GUMBY@THOTH.ACA.MCC.COM>
Date: 29 Feb 1988 14:15-EST
From: NGALL@G.BBN.COM
Date: 24 Feb 1988 19:20-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Cf. pg 187: "It is an error to try to use the KEYWORD package."
I don't see any problem with having the KEYWORD package use another package
(I don't see much point to it either). Do you?
Yes there is a problem: you could cause a symbol to be available as a
keyword whose value was not the keyword. E.g:
(setf user::keyword-example nil) ==> nil
(export 'user::keyword-example) ==> t
user:keyword-example ==> nil
(use-package '(user) (find-package 'keyword)) ==> t
:keyword-example ==> nil
:some-other-keyword ==> :some-other-keyword
This would break a lot of programs.
Don't think of keywords as symbols. They are a specialisation of
symbols; they don't have all the attributes (really only the PR and the
plist should be used) of symbols.
I think common-lisp should be explicit that you shouldn't think of them
as having all the attributes of symbols. Perhaps cl should specify that
"it is an error to use the function cell of a keyword," to discourage
people from using them as normal symbols.
∂01-Mar-88 0807 Common-Lisp-mailer the KEYWORD package USEing another package
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 1 Mar 88 08:07:23 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 1 Mar 88 11:07:00 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 1 Mar 88 11:06:54 EST
Date: Tue, 1 Mar 88 11:06 EST
From: Barry Margolin <barmar@Think.COM>
Subject: the KEYWORD package USEing another package
To: David Vinayak Wallace <Gumby@mcc.com>
Cc: NGALL@g.bbn.com, common-lisp@sail.stanford.edu
In-Reply-To: <880229230848.2.GUMBY@THOTH.ACA.MCC.COM>
Message-Id: <19880301160642.3.BARMAR@OCCAM.THINK.COM>
Date: Mon, 29 Feb 88 23:08 CST
From: David Vinayak Wallace <Gumby@mcc.com>
Date: 29 Feb 1988 14:15-EST
From: NGALL@G.BBN.COM
Date: 24 Feb 1988 19:20-PST
From: David Bein <pyrnj!pyramid!bein@rutgers.edu>
Cf. pg 187: "It is an error to try to use the KEYWORD package."
I don't see any problem with having the KEYWORD package use another package
(I don't see much point to it either). Do you?
Yes there is a problem: you could cause a symbol to be available as a
keyword whose value was not the keyword. E.g:
(setf user::keyword-example nil) ==> nil
(export 'user::keyword-example) ==> t
user:keyword-example ==> nil
(use-package '(user) (find-package 'keyword)) ==> t
:keyword-example ==> nil
Actually, this should result in an error due to an attempt to reference
an internal symbol as an external, because when a package uses another
package the symbols in the used package are internal to the using
package until it exports them. CLtL only says that symbols in the
keyword package are made external when they are added to the package,
not when they are accessed through indirection.
barmar
∂01-Mar-88 0854 Common-Lisp-mailer Re: the KEYWORD package USEing another package
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 1 Mar 88 08:53:53 PST
Date: 1 Mar 1988 11:54-EST
Sender: NGALL@G.BBN.COM
Subject: Re: the KEYWORD package USEing another package
From: NGALL@G.BBN.COM
To: Gumby@MCC.COM
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM] 1-Mar-88 11:54:50.NGALL>
In-Reply-To: <880229230848.2.GUMBY@THOTH.ACA.MCC.COM>
Date: Mon, 29 Feb 88 23:08 CST
From: David Vinayak Wallace <Gumby@MCC.COM>
...
Yes there is a problem: you could cause a symbol to be available as a
keyword whose value was not the keyword. E.g:
1 (setf user::keyword-example nil) ==> nil
2 (export 'user::keyword-example) ==> t
3 user:keyword-example ==> nil
4 (use-package '(user) (find-package 'keyword)) ==> t
5 :keyword-example ==> nil
What makes you think that reading and evaluating :keyword-example
results in NIL? Pg 175: "Any symbol preceded by a colon but no
package name ... is added to (or looked up in) the KEYWORD package as
an EXTERNAL symbol." After form 4, user:keyword-example is accessible
only as an INTERNAL symbol in the KEYWORD package. Therefore,
according to my interpretation of the preceding quote, whatever
mechanism "looks up" keyword::keyword-example (aka
user:keyword-example) would EXPORT it from the KEYWORD package,
thereby making it PRESENT in the KEYWORD package, and thereby causing
it to become a constant whose value is itself (all on pg 175). Thus
the value of form 5 would be printed as :keyword-example.
...
-- Nick
∂01-Mar-88 0910 Common-Lisp-mailer Re: the KEYWORD package USEing another package
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 1 Mar 88 09:10:04 PST
Date: 1 Mar 1988 12:10-EST
Sender: NGALL@G.BBN.COM
Subject: Re: the KEYWORD package USEing another package
From: NGALL@G.BBN.COM
To: barmar@THINK.COM
Cc: Gumby@MCC.COM, common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM] 1-Mar-88 12:10:14.NGALL>
In-Reply-To: <19880301160642.3.BARMAR@OCCAM.THINK.COM>
Date: Tue, 1 Mar 88 11:06 EST
From: Barry Margolin <barmar@Think.COM>
Date: Mon, 29 Feb 88 23:08 CST
From: David Vinayak Wallace <Gumby@mcc.com>
...
(setf user::keyword-example nil) ==> nil
(export 'user::keyword-example) ==> t
user:keyword-example ==> nil
(use-package '(user) (find-package 'keyword)) ==> t
:keyword-example ==> nil
Actually, this should result in an error due to an attempt to reference
an internal symbol as an external, because when a package uses another
package the symbols in the used package are internal to the using
package until it exports them. CLtL only says that symbols in the
keyword package are made external when they are added to the package,
not when they are accessed through indirection.
barmar
Yes. I retract my previous position (that symbols accessible in the
KEYWORD package are made external when they are ACCESSED) and agree
with Barry: a correctable error is signalled (pg. 174) when a symbol
that is internal to the KEYWORD package is referenced with the `:' (or
`keyword:') prefix.
Note that the only possible internal symbols in the KEYWORD package
are those that are inherited. Thus, one could `block' the addition of
certain symbols to the KEYWORD package by having the KEYWORD package
inherit them. This might be a useful way to `reserve' some set of
keywords.
-- Nick
∂01-Mar-88 1409 Common-Lisp-mailer the KEYWORD package USEing another package
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 1 Mar 88 14:09:14 PST
Received: from THOTH.ACA.MCC.COM by MCC.COM with TCP; Tue 1 Mar 88 16:09:25-CST
Date: Tue, 1 Mar 88 16:06 CST
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: the KEYWORD package USEing another package
To: NGALL@G.BBN.COM
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM] 1-Mar-88 11:54:50.NGALL>
Message-ID: <880301160628.2.GUMBY@THOTH.ACA.MCC.COM>
Date: 1 Mar 1988 11:54-EST
From: NGALL@G.BBN.COM
Date: Mon, 29 Feb 88 23:08 CST
From: David Vinayak Wallace <Gumby@MCC.COM>
...
Yes there is a problem: you could cause a symbol to be available as a
keyword whose value was not the keyword. E.g:
1 (setf user::keyword-example nil) ==> nil
2 (export 'user::keyword-example) ==> t
3 user:keyword-example ==> nil
4 (use-package '(user) (find-package 'keyword)) ==> t
5 :keyword-example ==> nil
What makes you think that reading and evaluating :keyword-example
results in NIL? Pg 175: "Any symbol preceded by a colon but no
package name ... is added to (or looked up in) the KEYWORD package as
an EXTERNAL symbol." After form 4, user:keyword-example is accessible
only as an INTERNAL symbol in the KEYWORD package. Therefore,
according to my interpretation of the preceding quote, whatever
mechanism "looks up" keyword::keyword-example (aka
user:keyword-example) would EXPORT it from the KEYWORD package,
thereby making it PRESENT in the KEYWORD package, and thereby causing
it to become a constant whose value is itself (all on pg 175). Thus
the value of form 5 would be printed as :keyword-example.
Should user::keyword-example now be nil or :keyword-example?
I actually tried the forms above in Symbolics Common Lisp and they
behave the way my example does. It's apparently a "bug" in that if you
poke around with FIND-SYMBOL you discover that the user:keyword-example
symbol is NOT exported from the keyword package.
I say "bug" because this behaviour should not really be defined. Should
making KEYWORD USE another package really change the value cells of the
inherited symbols? Or worse yet, according to your explanation above,
it shouldn't change the value until the symbol was read through the
KEYWORD package!? Plus you can end up with keywords with something in
their function cells, which always makes me queasy.
david
∂01-Mar-88 2351 Common-Lisp-mailer keywords revisited
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 1 Mar 88 23:51:20 PST
Received: from hplabs.HP.COM by SCORE.STANFORD.EDU with TCP; Tue 1 Mar 88 23:46:53-PST
Received: by hplabs.HP.COM ; Tue, 1 Mar 88 23:49:56 PST
Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424)
id AA05037; Tue, 1 Mar 88 23:35:39 PST
Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424)
id AA17261; Tue, 1 Mar 88 23:38:55 PST
Date: 1 Mar 1988 23:29-PST
From: David Bein <pyramid!bein@hplabs.HP.COM>
Subject: keywords revisited
To: hplabs!common-lisp@sail.stanford.edu
Message-Id: <573290979/bein@pyrnova>
Nick,
My idea of how all this ought to work is based on the idea that
any symbol accessible in the keyword package is in fact a keyword,
so that reading :FOOBAZ is always synonymous with
(INTERN "FOOBAZ" keyword-package)
If we allow any symbol to be accessible via using other packages or
having a symbol imported into the keyword package without
"keywordizing" it, then we violate the accessibility issues I have
raised. If we define keywordize in the brutal fashion described in:
(defun keywordize-symbol (symbol)
(let ((home (symbol-package symbol))
(key-package (find-package "KEYWORD")))
(unless (eq home key-package)
(if home (unintern symbol home))
(setf (symbol-value symbol) symbol)
(import symbol key-package))))
then allowing other interned symbols into the keyword package
does not violate my accessibility requirement. I think bashing
an interned symbol's home package and its value is somewhat
drastic. I dont feel as bad bashing a gensym or the result
of make-symbol.
To summarize, I think we should have done things this way:
(1) The keyword package is isolated, i.e. it never uses (or is used
by) other packages.
(2) Any symbol accessible in the keyword package is a keyword, i.e.
its home package is the keyword package and its value is itself.
(3) Symbols only become accessible in the keyword package via INTERN.
It is unclear to me why anyone would want to import a symbol which
is homed someplace else into the keyword package. My only concern is
that any symbols accessible in the keyword package be keywords. I
really dont like the problems which come up with reading/printing
given that reading :KEYWORD should produce a keyword. If a symbol
is accessible in the keyword package but not homed in the keyword
package, then it wont print as a keyword making one more subtle case
of read/print inconsistency. I guess I could have the reader
do a bunch of tricky things like shadow :-) ....
--David
p.s. Apologies if this came twice. Mailers are out to the beach these
days.
∂02-Mar-88 1203 Common-Lisp-mailer Request to be added to mailing list...
Received: from potomac.ads.com by SAIL.Stanford.EDU with TCP; 2 Mar 88 12:03:39 PST
Received: by potomac.ads.com (5.58/1.7)
id AA11771; Wed, 2 Mar 88 15:04:38 EST
Date: Wed, 2 Mar 88 15:04:38 EST
From: John T. Nelson <jtn%potomac@potomac.ads.com>
Message-Id: <8803022004.AA11771@potomac.ads.com>
To: ansi-common-request@potomac.ads.com, common-loops-request@potomac.ads.com,
common-windows-request@potomac.ads.com
Subject: Request to be added to mailing list...
We would like to be added to your mailing list. Sorry if I'm repeating
myself but we've had a few problems with ARPAnet. Please send the
common-windows, common-loops and ansi-common lists to their respective
addresses at our machine:
post-common-loops@potomac.ads.com
post-ansi-common@potomac.ads.com
post-common-windows@potomac.ads.com
Thanks.
John T. Nelson UUCP: sun!sundc!potomac!jtn
Advanced Decision Systems Internet: jtn@potomac.ads.com
1500 Wilson Blvd #512; Arlington, VA 22209-2401 (703) 243-1611
Strange... and beautiful music
∂06-Mar-88 1211 Common-Lisp-mailer A keyword data type
Received: from ICS.UCI.EDU by SAIL.Stanford.EDU with TCP; 6 Mar 88 12:11:27 PST
Received: from pasteur.uci.edu by ICS.UCI.EDU id aa06021; 6 Mar 88 12:11 PST
To: common-lisp%sail.stanford.edu@ICS.UCI.EDU
cc: kipps%etoile.uci.edu@ICS.UCI.EDU
Subject: A keyword data type
Date: Sun, 06 Mar 88 12:08:16 -0800
From: kipps%etoile.uci.edu@ICS.UCI.EDU
Message-ID: <8803061211.aa06021@ICS.UCI.EDU>
The comments I've heard so far about keywords lead me to believe that
there shouldn't be a keyword package at all; instead, there should be a
keyword data type, i.e., a data type of symbolic literals. A keyword data
object always evaluates to itself and has only one user-visible component,
its print name.
Because of their simplicity, keywords can be implemented more efficiently
than symbols (although this is probably of negligible consequence). What's
more important is that the integrity of keywords can no longer be
compromised as it is now. I find this approach to be cleaner than making
the keyword package "special" and more in line with the use of keywords in
CLtL. (Additional aspects of keywords should probably include the notion
of an uninterned keyword and a set of generic operations that can be applied
to keywords and symbols.) Is there any reason that keywords must be symbols?
-Kipps
∂08-Mar-88 0831 Common-Lisp-mailer A keyword data type
Received: from ICS.UCI.EDU by SAIL.Stanford.EDU with TCP; 8 Mar 88 08:31:18 PST
Received: from xx.lcs.mit.edu by ICS.UCI.EDU id aa08538; 8 Mar 88 8:29 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 8 Mar 88 11:27-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 83524; 8 Mar 88 11:27:08-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 96121; Tue 8-Mar-88 11:07:07-EST
Date: Tue, 8 Mar 88 11:06 est
From: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ICS.UCI.EDU>
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: kipps%etoile.uci.edu@ICS.UCI.EDU
Subject: A keyword data type
Cc: common-lisp%sail.stanford.edu@ICS.UCI.EDU
Message-ID: <8803080829.aa08538@ICS.UCI.EDU>
Date: Sun, 06 Mar 88 12:08:16 -0800
From: kipps%etoile.uci.edu@ICS.UCI.EDU
The comments I've heard so far about keywords lead me to believe that
there shouldn't be a keyword package at all; instead, there should be a
keyword data type, i.e., a data type of symbolic literals. A keyword data
object always evaluates to itself and has only one user-visible component,
its print name.
Frankly, I think this is a great idea. However, there are interactions with
various features. E.G., &key parameters. For the sake of
language extensions like CLOS, the identifiers for &key parameters are
not really going to be required to be "keywords" at all; rather, they
can be any symbol in any package. Use of real "keywords" for this just
saves making an extra symbol. We would need to change terminology
so that &key would become &name or &sym or something to avoid confusion.
A variation of your idea which might capture its value and yet avoid
turmoil in the CL world would be to make KEYWORD officially a subtype
of SYMBOL, and to exactly define which symbol operations work on this
subtype. My suggestion is that SYMBOL-NAME work, but not
SYMBOL-PLIST, SYMBOL-FUNCTION, SYMBOL-VALUE, etc. Currently, keywords
are real symbols, not a subtype, and therefore the issue arises of
whether you can IMPORT a keyword, etc.
....mike beckerle
Gold Hill
∂08-Mar-88 1142 Common-Lisp-mailer A keyword data type
Received: from ICS.UCI.EDU by SAIL.Stanford.EDU with TCP; 8 Mar 88 11:41:57 PST
Received: from think.com by ICS.UCI.EDU id aa14829; 8 Mar 88 11:36 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 8 Mar 88 14:34:31 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 8 Mar 88 14:34:25 EST
Date: Tue, 8 Mar 88 14:35 EST
From: Barry Margolin <barmar%think.com@ICS.UCI.EDU>
Subject: A keyword data type
To: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ICS.UCI.EDU>
Cc: kipps%etoile.uci.edu@ICS.UCI.EDU,
common-lisp%sail.stanford.edu@ICS.UCI.EDU
In-Reply-To: <8803080829.aa08538@ICS.UCI.EDU>
Message-Id: <19880308193551.6.BARMAR@OCCAM.THINK.COM>
Date: Tue, 8 Mar 88 11:06 est
From: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ics.uci.edu>
Date: Sun, 06 Mar 88 12:08:16 -0800
From: kipps%etoile.uci.edu@ICS.UCI.EDU
The comments I've heard so far about keywords lead me to believe that
there shouldn't be a keyword package at all; instead, there should be a
keyword data type, i.e., a data type of symbolic literals. A keyword data
object always evaluates to itself and has only one user-visible component,
its print name.
Frankly, I think this is a great idea. However, there are interactions with
various features. E.G., &key parameters. For the sake of
language extensions like CLOS, the identifiers for &key parameters are
not really going to be required to be "keywords" at all; rather, they
can be any symbol in any package. Use of real "keywords" for this just
saves making an extra symbol. We would need to change terminology
so that &key would become &name or &sym or something to avoid confusion.
Such a terminology change might be necessary whether or not keywords
were a distinct data type. Even without the new data type, the
"keywords" corresponding to &KEY parameters will not be required to be
keywords under the old definition (a symbol in the KEYWORD package).
A variation of your idea which might capture its value and yet avoid
turmoil in the CL world would be to make KEYWORD officially a subtype
of SYMBOL, and to exactly define which symbol operations work on this
subtype. My suggestion is that SYMBOL-NAME work, but not
SYMBOL-PLIST, SYMBOL-FUNCTION, SYMBOL-VALUE, etc. Currently, keywords
are real symbols, not a subtype, and therefore the issue arises of
whether you can IMPORT a keyword, etc.
Actually, I think that SYMBOL should be a subtype of KEYWORD! Anything
you can do to a keyword you can also do to a symbol, but not vice versa.
Using CLOS syntax (we'll need to get used to this soon):
(defclass keyword ()
((name :initarg name
:reader symbol-name)))
;;; This should actually be a shared slot, but I'm not sure how to
;;; access it in the allocate-instance meta-method, because I don't
;;; have Part 3 of the CLOS spec.
(defvar *keyword-table* nil)
(defmethod eval ((object keyword))
(symbol-value object))
(defmethod symbol-value ((object keyword))
object)
(defmethod initialize-instance :after ((object keyword) &rest ignore)
(unless (slot-boundp object 'name)
(error "A name must be specified.")))
(defmethod allocate-instance :around ((class (eql (symbol-class 'keyword)))
&key name &allow-other-keys)
(or (and (stringp name)
(find name *keyword-table* :key #'symbol-name :test #'string-equal))
(let ((object (call-next-method)))
(push object *keyword-table*)
object)))
(defun intern (string &optional package)
(if (or (eql package 'keyword) ; back-compatibility
(string-equal package "keyword"))
(make-instance 'keyword :name string)
(intern-in-package string package)))
(defclass symbol (keyword)
((value :accessor symbol-value
:writer set)
(function :accessor symbol-function)
(plist :initform nil
:accessor symbol-plist)
(package :initform nil
:reader symbol-package)))
(defun symbolp (object)
(typep object 'symbol))
(defun keywordp (object)
(and (typep object 'keyword)
(not (typep object 'symbol))))
I suspect the last function was the reason Mike said keywords should be
subtypes of symbols. I think the ultimate reason for this backwardness
is that the data types we really need are NAMED-OBJECT, with two
subtypes KEYWORD and SYMBOL.
barmar
∂09-Mar-88 1313 Common-Lisp-mailer defsys
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 9 Mar 88 13:13:08 PST
Received: from en-c06.prime.com by RELAY.CS.NET id aa09218; 9 Mar 88 15:09 EST
Received: from S51.Prime.COM by EN-C06.Prime.COM; 09 Mar 88 14:42:51 EST
Received: from ENX.Prime.COM by S51.Prime.COM; 09 Mar 88 14:43:28 EST
Received: from zaphod.prime.com by primerd.prime.com (3.2/SMI-3.0DEV3/smail)
id AA21223; Wed, 9 Mar 88 14:30:51 EST
Received: by zaphod.prime.com (3.2/SMI-3.2)
id AA01446; Wed, 9 Mar 88 14:35:59 EST
Date: Wed, 9 Mar 88 14:35:59 EST
From: Douglas Rand <doug@zaphod.prime.com>
Message-Id: <8803091935.AA01446@zaphod.prime.com>
To: common-lisp@SAIL.STANFORD.EDU
Subject: defsys
Folks,
I have a new version of the public domain defsys available but I need
someone with either access to sail or who is willing to provide it a good
home. My usual contact seems to have failed me. Send responses to
doug@zaphod.prime.com, I appologize for sending this to the whole list
but my options seem limited.
Cheers,
Doug
∂09-Mar-88 1843 Common-Lisp-mailer CLOS Consortium
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Mar 88 18:43:03 PST
Received: by labrea.Stanford.EDU; Wed, 9 Mar 88 18:43:49 PST
Received: from bhopal.lucid.com by edsel id AA14794g; Wed, 9 Mar 88 18:28:38 PST
Received: by bhopal id AA09672g; Wed, 9 Mar 88 18:35:03 PST
Date: Wed, 9 Mar 88 18:35:03 PST
From: Linda G. DeMichiel <edsel!lgd@labrea.Stanford.EDU>
Message-Id: <8803100235.AA09672@bhopal.lucid.com>
To: common-lisp-object-system@sail.Stanford.EDU, common-lisp@sail.Stanford.EDU
Subject: CLOS Consortium
Cc: gregor@xerox.com, lgd@sail.Stanford.EDU, rpg@sail.Stanford.EDU
CLOS Consortium
Lucid is currently pursuing the establishment of a consortium to do a
high-performance implementation of the Common Lisp Object System.
The suggested organization for this consortium is the following: Each
member company is to supply either programmers or money, and the
consortium will select a group of individuals to do the implementation
(in the case that more programmers are offered than needed). It is
likely that the current PCL will become the seed for this
implementation. No restrictions will exist as to which companies may
become members of the consortium, and we expect that the implementors
would be from various companies. The result will be a set of sources
either in the public domain or owned by the member companies.
Lucid offers to contribute at least one highly-talented programmer and
the organization for the program.
A mechanism should also be established to handle companies who want to
join the consortium at a later date.
We will be holding an organizational meeting during X3J13 next week
for anyone who may be interested in participating. This meeting is
scheduled for Tuesday, March 15, 8:00p.m., at Hyatt Rickeys,
4219 El Camino Real, Palo Alto.
If you are interested in joining and cannot make the meeting,
please let me know.
Linda DeMichiel
Lucid, Inc.
415-329-8400
∂10-Mar-88 1641 Common-Lisp-mailer Re: A keyword data type
Received: from ICS.UCI.EDU by SAIL.Stanford.EDU with TCP; 10 Mar 88 16:41:13 PST
Received: by ICS.UCI.EDU id ab24419; 10 Mar 88 16:40 PST
Received: from pasteur.uci.edu by ICS.UCI.EDU id aa24388; 10 Mar 88 16:38 PST
To: Barry Margolin <barmar%think.com@ICS.UCI.EDU>
cc: "mike@gold-hill.com after 1-April-88" <mike%acorn%live-oak.lcs.mit.edu@ICS.UCI.EDU>,
common-lisp%sail.stanford.edu@ICS.UCI.EDU
Subject: Re: A keyword data type
In-reply-to: Your message of Tue, 08 Mar 88 14:35:00 -0500.
<19880308193551.6.BARMAR@OCCAM.THINK.COM>
Date: Thu, 10 Mar 88 16:35:09 -0800
From: kipps%etoile.uci.edu@ICS.UCI.EDU
Message-ID: <8803101638.aa24388@ICS.UCI.EDU>
My purpose in suggesting a keyword data type was to make a definite
distinction between symbols and keywords. Making one a subtype of the
other does not do this. A type/subtype relation does not merely depend
on commonality of operations, but of purpose and use. Keywords and
symbols do not serve the same purpose. Keywords are used as symbolic
literals, while symbols are used as identifiers (i.e., indirect
references to values, functions, etc.). Thus, it does not seem right
to make one the subtype of the other. My own suggestion would be to
call symbols identifiers and create a new type called symbols which
is a super of both identifier and keyword, e.g.,
symbol
/ \
identifier keyword
Unfortunately, this suggestion would introduce even more terminology
changes; so it goes.
-Kipps
∂11-Mar-88 1105 Common-Lisp-mailer &REST lists
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Mar 88 11:05:15 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 361155; Fri 11-Mar-88 14:04:03 EST
Date: Fri, 11 Mar 88 14:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: &REST lists
To: Scott E. Fahlman <Fahlman@C.CS.CMU.EDU>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <FAHLMAN.12364037774.BABYL@C.CS.CMU.EDU>
Message-ID: <19880311190404.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 4 Jan 1988 20:27 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Is there general agreement on whether it is valid Common Lisp to
destructively modify (RPLACA, RPLACD) the list to which a &REST
parameter is bound? I can't find a reference in CLtL for this.
I think there's general agreement that &rest args are supposed to be
righteous lists with indefinite extent, so RPLAC'ing them ought to be
legal.
I don't think I ever remembered to answer this. This is specious
reasoning. The premise that values of &rest parameters have indefinite
extent does not imply the conclusion that each value of an &rest
parameter is an independent object that does not share structure with
any other object. There is general agreement on the premise, but
certainly not on the conclusion.
Please don't confuse the issue of extent, on which Symbolics still
deliberately violates the standard (this is a well-known, documented
violation, which will go away when we get the resources to make it
go away) with the issue of structure sharing.
∂11-Mar-88 1147 Common-Lisp-mailer &REST lists
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 11 Mar 88 11:47:31 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU.#Internet>; Fri 11 Mar 88 14:47:20-EST
Date: Fri, 11 Mar 1988 14:47 EST
Message-ID: <FAHLMAN.12381539395.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST lists
In-reply-to: Msg of 11 Mar 1988 14:04-EST from David A. Moon <Moon at STONY-BROOK.SCRC.Symbolics.COM>
In response to David A. Moon <Moon at STONY-BROOK.SCRC.Symbolics.COM>...
Yes, I misunderstood the question about RPLACA and &rest args. Since
whoever asked the question did not mention the case of APPLY, I didn't
realize that shared lists were the issue. I thought it was a question
about whether the &rest list could be treated as a real list.
-- Scott
∂11-Mar-88 1306 Common-Lisp-mailer the array type mess....
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Mar 88 13:04:43 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 361275; Fri 11-Mar-88 16:02:53 EST
Date: Fri, 11 Mar 88 16:02 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: the array type mess....
To: Ram@C.CS.CMU.EDU
cc: Jon L White <edsel!jonl@LABREA.STANFORD.EDU>, common-lisp@SAIL.STANFORD.EDU,
sandra%orion@CS.UTAH.EDU
In-Reply-To: <RAM.12365298662.BABYL@>
Message-ID: <19880311210247.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
I agree with your points about definitional versus implementation types.
Is it a correct summary of your comments that you want the distinction
(CLtL p.45) between declaration and discrimination to be eliminated,
with TYPEP being changed to treat array type specifiers in precisely the
way that CLtL calls "for declaration"?
To say the same thing in Lisp:
(TYPEP array '(ARRAY type *))
is currently defined to be equivalent to:
(AND (TYPEP array '(ARRAY * *))
(SUBTYPEP (ARRAY-ELEMENT-TYPE array) 'type)
(SUBTYPEP 'type (ARRAY-ELEMENT-TYPE array)))
I don't think you're proposing to make it equivalent to:
(AND (TYPEP array '(ARRAY * *))
(SUBTYPEP 'type (ARRAY-ELEMENT-TYPE array)))
but rather to make it equivalent to:
(LET ((TYPE1 (IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE 'type)))
(AND (TYPEP array '(ARRAY * *))
(SUBTYPEP (ARRAY-ELEMENT-TYPE array) TYPE1)
(SUBTYPEP TYPE1 (ARRAY-ELEMENT-TYPE array))))
where an inefficient but portable definition is:
(DEFUN IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE (TYPE)
(ARRAY-ELEMENT-TYPE (MAKE-ARRAY 0 :ELEMENT-TYPE TYPE))
Is this accurate?
Let's look at the various things (TYPEP array '(ARRAY TYPE *)) => T
might mean, and what they mean with that proposal:
(TYPEP x TYPE) means x can safely be stored into the array: yes
(TYPEP x TYPE) is true for all current elements of the array: no
(TYPEP x TYPE) is true for all future elements of the array: no
(NOT (TYPEP x TYPE)) means x cannot be safely stored into the array: no
with CLtL's current definition of TYPEP:
(TYPEP x TYPE) means x can safely be stored into the array: yes
(TYPEP x TYPE) is true for all current elements of the array: yes
(TYPEP x TYPE) is true for all future elements of the array: yes
(NOT (TYPEP x TYPE)) means x cannot be safely stored into the array: yes
So what we're saying is that for the latter two tests you must use
ARRAY-ELEMENT-TYPE, and for the second test you must look at the
actual contents of the array. That's probably okay, especially
when one considers that in CLtL (TYPEP array '(ARRAY TYPE *)) very
rarely returns T, and for most values of TYPE it is implementation
dependent.
(ARRAY T) remains a proper subset of (ARRAY *), and (STRING size) remains
an abbreviation for (ARRAY STRING-CHAR (size)), for the simple reason
that CLtL requires (IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE 'STRING-CHAR)
=> STRING-CHAR (or a type specifier equivalent to STRING-CHAR).
Should the IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE function I have
postulated as hidden inside TYPEP be made available as a standard function?
An interesting comment on all this is that we are implicitly assuming
that an implementation's spectrum of specialized array types is independent
of the size, number of dimensions, indirectness, or adjustability of the
array. This seems unlikely to be true of all implementations. I don't
know how to fix this deficiency.
Someone should write this up in Cleanup form and thus give us all
a chance to think about it more deeply.
∂11-Mar-88 1344 Common-Lisp-mailer Re: &REST lists
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 11 Mar 88 13:44:09 PST
Date: 11 Mar 1988 16:42-EST
Sender: NGALL@G.BBN.COM
Subject: Re: &REST lists
From: NGALL@G.BBN.COM
To: Moon@SCRC-STONY-BROOK.ARPA
Cc: Fahlman@C.CS.CMU.EDU, common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]11-Mar-88 16:42:56.NGALL>
In-Reply-To: <19880311190404.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Hmm... I'm getting a little confused by the issue of structure-sharing
the CONS object (and the CONSes linked to it) that is the value of an
&REST parameter. In general, there are two consequences of structure
sharing:
1) (The one alluded to in your message.) If one modifies the CAR or
CDR cell of a shared CONS, other parts of the system may be affected
(e.g., a calling function call form could be modified).
2) (This is the one that bothers me.) Some other part of the system
may modifiy a shared CONS at any time. This means that although the
list (chain of CONSes) that is the value of the &REST parameter has
indefinite extent, some part of the system (e.g., some internal part
of the function calling mechanism) could modify the CAR or CDR cell of
any of the CONSes. For example, I could assign the value of the &REST
parameter (e.g., the list (1 2 3)) to the special variable *FOO*,
return from the function, and discover that the value of *FOO* is now
(1 . !!!END!!!). The CONS is still there, but someone else (e.g., the
function-return mechanism) modified its CDR cell.
If you are suggesting that (2) would be possible under the
clarification of &REST, then saving the value of the &REST parameter
is fairly useless. One would have to COPY it to prevent it from being
smashed.
If on the other hand, you are promising that a CL implementation will
never (internally) modify any CONS comprising the list that is the
value of an &REST parameter, then this should be stated explicitly in
the clarification to &REST.
In summary, stating that "the CONSes of the &REST list have indefinite
extent, but may be shared by other parts of the system", implicitly
allows the behavior mentioned in (2), and this makes saving the CONSes
relatively useless.
-- Nick
...
Date: Fri, 11 Mar 88 14:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
... The premise that values of &rest parameters have indefinite
extent does not imply the conclusion that each value of an &rest
parameter is an independent object that does not share structure with
any other object. There is general agreement on the premise, but
certainly not on the conclusion.
Please don't confuse the issue of extent, on which Symbolics still
deliberately violates the standard (this is a well-known, documented
violation, which will go away when we get the resources to make it
go away) with the issue of structure sharing.
∂11-Mar-88 1410 Common-Lisp-mailer &REST lists
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 11 Mar 88 14:10:36 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU.#Internet>; Fri 11 Mar 88 17:03:43-EST
Date: Fri, 11 Mar 1988 17:03 EST
Message-ID: <FAHLMAN.12381564223.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST lists
In-reply-to: Msg of 11 Mar 1988 16:42-EST from NGALL at G.BBN.COM
In reply to NGALL at G.BBN.COM ...
I believe that there is only one way in which the backbone of an &rest
list might end up being shared, and that is if the list was passed in as
the last arg to APPLY. In all other cases, the &rest list is built up
from distinct arguments, and couldn't possibly be anything that the user
has his hands on. We had a lengthy debate at one time about the APPLY
case: should we guarantee the user that the &rest list is a fresh copy,
guarantee that the APPLY list is incorporated into the &rest list, or
not guarantee anything. I believe that we never reached a firm decision
on this, which means that the "not guarantee anything" case wins by
default. So smashing a &rest arg list is not a good idea unless you
know where it came from and who else might have hold of it. As Steele
pointed out, smashing anything is not a good idea unless you know its
pedigree. If you want to be safe, copy it before smashing.
-- Scott
∂11-Mar-88 1430 Common-Lisp-mailer &REST lists
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 11 Mar 88 14:30:44 PST
Received: ID <FAHLMAN@C.CS.CMU.EDU.#Internet>; Fri 11 Mar 88 17:30:50-EST
Date: Fri, 11 Mar 1988 17:30 EST
Message-ID: <FAHLMAN.12381569161.BABYL@C.CS.CMU.EDU>
Sender: FAHLMAN@C.CS.CMU.EDU
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST lists
In-reply-to: Msg of 11 Mar 1988 16:42-EST from NGALL at G.BBN.COM
To further clarify, I don't think that anyone is proposing that &rest
lists should be mysteriously modified by the system itself in a Common
Lisp that adheres to the standard.
-- Scott
∂11-Mar-88 1434 Common-Lisp-mailer Re: &REST lists
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Mar 88 14:34:15 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 361398; Fri 11-Mar-88 17:33:32 EST
Date: Fri, 11 Mar 88 17:33 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: &REST lists
To: NGALL@G.BBN.COM
cc: Fahlman@C.CS.CMU.EDU, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM]11-Mar-88 16:42:56.NGALL>
Message-ID: <19880311223331.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 11 Mar 1988 16:42-EST
From: NGALL@G.BBN.COM
Hmm... I'm getting a little confused by the issue of structure-sharing
the CONS object (and the CONSes linked to it) that is the value of an
&REST parameter. In general, there are two consequences of structure
sharing:
1) (The one alluded to in your message.) If one modifies the CAR or
CDR cell of a shared CONS, other parts of the system may be affected
(e.g., a calling function call form could be modified).
2) (This is the one that bothers me.) Some other part of the system
may modifiy a shared CONS at any time.
It's not considered kosher to modify shared data structure without documenting
that you do so.
This means that although the
list (chain of CONSes) that is the value of the &REST parameter has
indefinite extent, some part of the system (e.g., some internal part
of the function calling mechanism) could modify the CAR or CDR cell of
any of the CONSes.
I don't see anything in CLtL that says the function calling mechanism is
allowed to modify things.
For example, I could assign the value of the &REST
parameter (e.g., the list (1 2 3)) to the special variable *FOO*,
return from the function, and discover that the value of *FOO* is now
(1 . !!!END!!!). The CONS is still there, but someone else (e.g., the
function-return mechanism) modified its CDR cell.
If you are suggesting that (2) would be possible under the
clarification of &REST, then saving the value of the &REST parameter
is fairly useless. One would have to COPY it to prevent it from being
smashed.
I'm not suggesting this.
If on the other hand, you are promising that a CL implementation will
never (internally) modify any CONS comprising the list that is the
value of an &REST parameter, then this should be stated explicitly in
the clarification to &REST.
You're right. It would be good to state explicitly that the function
call mechanism will not bash lists received as values of &REST parameters,
that users should not bash lists received as values of &REST parameters,
and that users should not bash lists passed to APPLY as its last argument.
Of course the same thing could be said about every other place in the
language where potentially shareable structure exists.
∂11-Mar-88 1457 Common-Lisp-mailer &REST lists
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 11 Mar 88 14:56:58 PST
Received: by labrea.Stanford.EDU; Fri, 11 Mar 88 14:57:41 PST
Received: from kent-state.lucid.com by edsel id AA21370g; Fri, 11 Mar 88 14:37:24 PST
Received: by kent-state id AA04701g; Fri, 11 Mar 88 14:45:59 PST
Date: Fri, 11 Mar 88 14:45:59 PST
From: Eric Benson <edsel!eb@labrea.Stanford.EDU>
Message-Id: <8803112245.AA04701@kent-state.lucid.com>
To: Fahlman@c.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: "Scott E. Fahlman"'s message of Fri, 11 Mar 1988 17:03 EST <FAHLMAN.12381564223.BABYL@C.CS.CMU.EDU>
Subject: &REST lists
It's not only smashing a &rest argument that's a problem, it's
smashing any list that has been given as the last argument to APPLY as
well. Consider the following in an implementation that doesn't copy
the last argument to APPLY when it is passed as a &rest argument:
> (defvar *message*)
*MESSAGE*
> (defun set-message (&rest mess)
(setq *message* mess))
SET-MESSAGE
> (let ((winner (list 'a 'winner)))
(apply #'set-message winner)
(setf (cdr winner) (list 'loser))
winner)
(A LOSER)
Is *message* (A WINNER) or (A LOSER)? (It might be
(#<DTP-LOCATIVE 76123756> #<DTP-ODD-PC 12313453> ...)
but that's a different problem.) This suggests that once a list has
been given as the last argument to APPLY it is no longer OK to modify
it.
∂11-Mar-88 1606 Common-Lisp-mailer Re: &REST lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 11 Mar 88 16:00:07 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 11 Mar 88 17:39:02 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 11 Mar 88 17:38:58 EST
Date: Fri, 11 Mar 88 17:40 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: &REST lists
To: NGALL@g.bbn.com
Cc: Moon@stony-brook.scrc.symbolics.com, Fahlman@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <[G.BBN.COM]11-Mar-88 16:42:56.NGALL>
Message-Id: <19880311224022.7.BARMAR@OCCAM.THINK.COM>
Date: 11 Mar 1988 16:42-EST
From: NGALL@g.bbn.com
2) (This is the one that bothers me.) Some other part of the system
may modifiy a shared CONS at any time. This means that although the
list (chain of CONSes) that is the value of the &REST parameter has
indefinite extent, some part of the system (e.g., some internal part
of the function calling mechanism) could modify the CAR or CDR cell of
any of the CONSes. For example, I could assign the value of the &REST
parameter (e.g., the list (1 2 3)) to the special variable *FOO*,
return from the function, and discover that the value of *FOO* is now
(1 . !!!END!!!). The CONS is still there, but someone else (e.g., the
function-return mechanism) modified its CDR cell.
I don't think that he was suggesting that the conses could be smashed
behind your back by some automatic mechanism like returning from a
function call. I think the following is an example of the sharing of
&REST lists that may be possible.
(defparameter *shared-list* '(1 2 3))
(defun function-1 (&rest args)
(function-2)
(print args))
(defun function-2 ()
(setf (car *shared-list*) 6))
(defun caller ()
(apply #'function-1 *shared-list*))
OK, what does (caller) print, (1 2 3) or (6 2 3)? In Genera it prints
the latter. Thus, one must be careful when passing argument lists that
can be accessed by other functions.
barmar
∂11-Mar-88 1638 Common-Lisp-mailer Re: &REST lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 11 Mar 88 16:38:28 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 11 Mar 88 17:39:02 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 11 Mar 88 17:38:58 EST
Date: Fri, 11 Mar 88 17:40 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: &REST lists
To: NGALL@g.bbn.com
Cc: Moon@stony-brook.scrc.symbolics.com, Fahlman@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <[G.BBN.COM]11-Mar-88 16:42:56.NGALL>
Message-Id: <19880311224022.7.BARMAR@OCCAM.THINK.COM>
Date: 11 Mar 1988 16:42-EST
From: NGALL@g.bbn.com
2) (This is the one that bothers me.) Some other part of the system
may modifiy a shared CONS at any time. This means that although the
list (chain of CONSes) that is the value of the &REST parameter has
indefinite extent, some part of the system (e.g., some internal part
of the function calling mechanism) could modify the CAR or CDR cell of
any of the CONSes. For example, I could assign the value of the &REST
parameter (e.g., the list (1 2 3)) to the special variable *FOO*,
return from the function, and discover that the value of *FOO* is now
(1 . !!!END!!!). The CONS is still there, but someone else (e.g., the
function-return mechanism) modified its CDR cell.
I don't think that he was suggesting that the conses could be smashed
behind your back by some automatic mechanism like returning from a
function call. I think the following is an example of the sharing of
&REST lists that may be possible.
(defparameter *shared-list* '(1 2 3))
(defun function-1 (&rest args)
(function-2)
(print args))
(defun function-2 ()
(setf (car *shared-list*) 6))
(defun caller ()
(apply #'function-1 *shared-list*))
OK, what does (caller) print, (1 2 3) or (6 2 3)? In Genera it prints
the latter. Thus, one must be careful when passing argument lists that
can be accessed by other functions.
barmar
∂11-Mar-88 2022 Common-Lisp-mailer the array type mess....
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 11 Mar 88 20:22:24 PST
Received: by labrea.Stanford.EDU; Fri, 11 Mar 88 20:23:06 PST
Received: from bhopal.lucid.com by edsel id AA02102g; Fri, 11 Mar 88 20:03:14 PST
Received: by bhopal id AA13617g; Fri, 11 Mar 88 20:10:04 PST
Date: Fri, 11 Mar 88 20:10:04 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8803120410.AA13617@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: Ram@c.cs.cmu.edu, common-lisp@sail.stanford.edu, sandra%orion@cs.utah.edu
In-Reply-To: David A. Moon's message of Fri, 11 Mar 88 16:02 EST <19880311210247.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: the array type mess....
re: To say the same thing in Lisp:
. . .
(DEFUN IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE (TYPE)
(ARRAY-ELEMENT-TYPE (MAKE-ARRAY 0 :ELEMENT-TYPE TYPE))
. . .
Should the IMPLEMENTATION-DEPENDENT-ARRAY-ELEMENT-TYPE function I have
postulated as hidden inside TYPEP be made available as a standard function?
Your summary here is essentially the same as the proposal I sent to
CL-CLEANUP on March 1, except I named it UPGRADE-ARRAY-ELEMENT-TYPE
to suggest that a possibly-non-trival super-type would be returned.
Also, I think the functionality underlying UPGRADE-ARRAY-ELEMENT-TYPE
is already in everyone's arrays implementation, regardless of how they
handle the TYPEP mess. For those not on the cl-cleanup list, I've
excerpted the relevant message below.
Date: Tue, 1 Mar 88 13:09:10 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
To: Moon@stony-brook.scrc.symbolics.com
Cc: cl-cleanup@sail.stanford.edu, vanroggen%aitg.decnet@hudson.dec.com,
Ram@c.cs.cmu.edu
Subject: UPGRADE-ARRAY-ELEMENT-TYPE: a sloution for the array TYPEP problem
. . . a function (which
would be "implementation revealing") named UPGRADE-ARRAY-ELEMENT-TYPE
whose purpose would be to tell you what the canonical representation for a
type name is (when used as an :element-type specifier).
. . .
[why not toss out "upgrading" altogether? because ...]
to make types absolutely portable this way is a very pyrrhic success.
Sure, your program will port to the Y machine -- it will just run two
orders of magnitude slower [because you started out on, say, a Multics
machine with (MOD 512) arrays optimized, and ported to an implementation
for an engineering workstation that prefers (UNSIGNED-BYTE 8) arrays ...].
Finally, as I've said before, I don't think it's an acceptable solution
for Lisp to take the same route as C (and others) to achieve portability.
The kinds of array types in such languages are limited to a small (albeit
very useful) set that seems inspired by one particular hardware
architecture.
-- JonL --
P.S. Of course UPGRADE-ARRAY-ELEMENT-TYPE can currently be implemented
in a "consy" way doing something like:
(array-element-type (make-array 0 :element-type 'foo))
But the presence of a "first class" function UPGRADE-ARRAY-ELEMENT-TYPE
would be more for the purpose of encouraging cognizance of these
problems than for avoiding the consing. Implicitly, such a function
lies underneath any implementation of MAKE-ARRAY already.
Date: Tue, 1 Mar 88 14:05:25 PST
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
To: Ram@c.cs.cmu.edu
Cc: cl-cleanup@sail.stanford.edu, Moon@scrc-stony-brook.arpa,
vanroggen%aitg.decnet@hudson.dec.com
Subject: function-type-rest-list-element (really array types)
...
This may be another way of trying to say that
`(ARRAY FOO)
is type equivalent to
`(ARRAY ,(upgrade array-element-type 'foo))
-- JonL --
∂13-Mar-88 0449 Common-Lisp-mailer &rest lists - correction
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 13 Mar 88 04:48:57 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA27623; Sun, 13 Mar 88 07:49:30 EST
From: mcvax!pilatus!ceb@uunet.UU.NET
Received: by mcvax.cwi.nl; Sun, 13 Mar 88 13:47:10 +0100 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA20851; Sun, 13 Mar 88 13:22:41 +0100
Date: Sun, 13 Mar 88 13:22:41 +0100
Message-Id: <8803131222.AA20851@cernvax.uucp>
To: common-lisp@sail.stanford.edu
Subject: &rest lists - correction
In my previous posting, the counter example should have read
(setf (cdar ..) .), since (setf (cadr ..) .) *would* be covered by
backbone copying. Hope this didn't cloud things.
I grow rusty on "under-the-hood tinkering", since I now use mainly
semantically cleaner defstructs.
∂13-Mar-88 0449 Common-Lisp-mailer &rest lists and other things ground through function application
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 13 Mar 88 04:49:01 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA27626; Sun, 13 Mar 88 07:49:36 EST
From: mcvax!pilatus!ceb@uunet.UU.NET
Received: by mcvax.cwi.nl; Sun, 13 Mar 88 13:47:31 +0100 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA20860; Sun, 13 Mar 88 13:22:44 +0100
Date: Sun, 13 Mar 88 13:22:44 +0100
Message-Id: <8803131222.AA20860@cernvax.uucp>
To: common-lisp@sail.stanford.edu
Subject: &rest lists and other things ground through function application
With regards the current (or, by the time this message makes it back,
probably two week old) debate on this topic, I have yet to see the
following point mentioned:
If you want to be able to freely modify the structures which are
used to implement these features, something imbedded in the kernel of
the language is going to have to *copy* them.
You could do a top-level copy, but then you are still not protected if
someone does a (setf (cadr passed-argument-structure 'truc). In order
to beat this, you have to do an arbitrary depth copy, and then, when
you pass tangled, circular, non-ending horrible things which make
print go bananas (I do this often), you have to do circular list
detection, etc. . . . and you very quickly get into a game which can't
be won.
This is a problem which defies mechanical solution, and should be
kept out of the language definition, except, as someone has already
pointed out, for a clear staking of position in the standard.
ceb
∂14-Mar-88 0847 Common-Lisp-mailer New defsys available for public anonymous ftp
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 14 Mar 88 08:46:59 PST
Received: from en-c06.prime.com by RELAY.CS.NET id aa25561; 14 Mar 88 10:39 EST
Received: from S51.Prime.COM by EN-C06.Prime.COM; 14 Mar 88 10:23:20 EST
Received: from ENX.Prime.COM by S51.Prime.COM; 14 Mar 88 10:23:42 EST
Received: from zaphod.prime.com by primerd.prime.com (3.2/SMI-3.0DEV3/smail)
id AA28064; Mon, 14 Mar 88 10:12:26 EST
Received: by zaphod.prime.com (3.2/SMI-3.2)
id AA03232; Mon, 14 Mar 88 10:17:38 EST
Date: Mon, 14 Mar 88 10:17:38 EST
From: Douglas Rand <doug@zaphod.prime.com>
Message-Id: <8803141517.AA03232@zaphod.prime.com>
To: common-lisp@SAIL.STANFORD.EDU
Subject: New defsys available for public anonymous ftp
Jim Larus has been kind enough to provide a new home for defsys on ucbarpa.
Use anonymous login to retrieve defsys.doc and defsys.lisp from pub/ on
ucbarpa.
Cheers,
Doug
∂14-Mar-88 2257 Common-Lisp-mailer &Rest Lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 14 Mar 88 22:53:25 PST
Received: from relay2.cs.net by RELAY.CS.NET id aa06767; 15 Mar 88 1:37 EST
Received: from cs.umass.edu by RELAY.CS.NET id cb01442; 15 Mar 88 1:26 EST
Date: Mon, 14 Mar 88 14:38 EDT
From: ELIOT@cs.umass.edu
Subject: &Rest Lists
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
Ideally &Rest arguments should be the exclusive property of the
function which defines them. Two funny restrictions have sometimes
been imposed on &Rest lists to enable certain optimizations. The
question is whether the value of the optimization exceeds the cost
of documenting and not violating the restrictions.
The first optimization/restriction primarilly allows stack-consing at the
expense of making &Rest lists become undefined when the function returns.
This is a fairly large optimization but it has already been prohibited
(in the general case) by CLtL.
The second optimization/restriction primarilly allows constant lists to
be used as &Rest lists at the expense of prohibiting functions from
modifying their &rest lists. However, since CLtL already requires
&Rest lists to exist after the function returns they will almost
always have to be CONSed as the function is called, unless fancy
optimizations have occured. The primary case where this optimization
still could matter is when Apply is used with a constant list to call
a function with an &Rest list that does not have to be modified.
I think that this optimization is rather minor, except in situations
where a programmer has intentionally set up the code to take advantag
of this. However, it is a simple matter to rework this kind of function
call to get the optimized behavior in a fully portable way.
Instead of:
(defun bar (x)
(apply #'foo x))
(defun foo (&rest theList)
...)
Use:
(defun bar (x)
(foo x))
(defun foo (theList)
...)
This new code is guaranteed to be portable and efficient, and it is
also easier to read. Admittedly this rewrite isn't good for 100%
of the cases, but it does make the optimized behavior of &Rest lists
less important. Sufficiently so that I think &Rest lists should
be implemented so that they behave as if:
(defun foo (&rest x) ...)
Should behave as if it were defined:
(defun foo (&rest G0047) ;Gensym really
(let ((x (copy-list G0047)))
...))
I think this fully and precisely specifies the semantics of &Rest.
Chris Eliot
∂16-Mar-88 1158 Common-Lisp-mailer &Rest Lists
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 16 Mar 88 11:58:21 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 15 Mar 88 11:14-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 84390; 15 Mar 88 11:07:32-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 96800; Tue 15-Mar-88 10:08:06-EST
Date: Tue, 15 Mar 88 10:09 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: ELIOT@cs.umass.edu
Subject: &Rest Lists
Cc: common-lisp@SAIL.STANFORD.EDU
(defun foo (&rest x) ...)
Should behave as if it were defined:
(defun foo (&rest G0047) ;Gensym really
(let ((x (copy-list G0047)))
...))
I think this fully and precisely specifies the semantics of &Rest.
Chris Eliot
I couldn't disagree more. This implementation prohibits the
programmer from exploiting sharing of list substructure. It really
takes away some expressive power. One can get back the behavior
that you want with the transform you've outlined here.
Common lisp is not a functional language, it has tons of destructive
operations. It is out of character for such a language to prohibit
sharing of substructure by copying data structures implicitly.
In general, when destructive operations are being used it should be the
programmer's responsibility to copy a data structure manually.
&REST should never cause copying of a list passed to it from APPLY.
...mike beckerle
GOLD HILL
∂16-Mar-88 1349 Common-Lisp-mailer &Rest Lists
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 16 Mar 88 11:58:21 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 15 Mar 88 11:14-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 84390; 15 Mar 88 11:07:32-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 96800; Tue 15-Mar-88 10:08:06-EST
Date: Tue, 15 Mar 88 10:09 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: ELIOT@cs.umass.edu
Subject: &Rest Lists
Cc: common-lisp@SAIL.STANFORD.EDU
(defun foo (&rest x) ...)
Should behave as if it were defined:
(defun foo (&rest G0047) ;Gensym really
(let ((x (copy-list G0047)))
...))
I think this fully and precisely specifies the semantics of &Rest.
Chris Eliot
I couldn't disagree more. This implementation prohibits the
programmer from exploiting sharing of list substructure. It really
takes away some expressive power. One can get back the behavior
that you want with the transform you've outlined here.
Common lisp is not a functional language, it has tons of destructive
operations. It is out of character for such a language to prohibit
sharing of substructure by copying data structures implicitly.
In general, when destructive operations are being used it should be the
programmer's responsibility to copy a data structure manually.
&REST should never cause copying of a list passed to it from APPLY.
...mike beckerle
GOLD HILL
∂16-Mar-88 1729 Common-Lisp-mailer &Rest Lists
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 16 Mar 88 11:58:21 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 15 Mar 88 11:14-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 84390; 15 Mar 88 11:07:32-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 96800; Tue 15-Mar-88 10:08:06-EST
Date: Tue, 15 Mar 88 10:09 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: ELIOT@cs.umass.edu
Subject: &Rest Lists
Cc: common-lisp@SAIL.STANFORD.EDU
(defun foo (&rest x) ...)
Should behave as if it were defined:
(defun foo (&rest G0047) ;Gensym really
(let ((x (copy-list G0047)))
...))
I think this fully and precisely specifies the semantics of &Rest.
Chris Eliot
I couldn't disagree more. This implementation prohibits the
programmer from exploiting sharing of list substructure. It really
takes away some expressive power. One can get back the behavior
that you want with the transform you've outlined here.
Common lisp is not a functional language, it has tons of destructive
operations. It is out of character for such a language to prohibit
sharing of substructure by copying data structures implicitly.
In general, when destructive operations are being used it should be the
programmer's responsibility to copy a data structure manually.
&REST should never cause copying of a list passed to it from APPLY.
...mike beckerle
GOLD HILL
∂16-Mar-88 1747 Common-Lisp-mailer &REST args
Received: from nrtc.nrtc.northrop.com (NRTC.NORTHROP.COM) by SAIL.Stanford.EDU with TCP; 16 Mar 88 17:47:21 PST
Date: Wed, 16 Mar 88 15:35:28 PST
From: Jeff Barnett <jbarnett@nrtc.northrop.com>
To: common-lisp@sail.stanford.edu
Subject: &REST args
In regards to the properties of &REST arguments: There may be a way to
have our cake and eat it too given that CL has a declaration mechanism
in place already and optimization hints are considered first class citizens.
I propose an anology to the SYS:DOWNWARD-FUNCTION and SYS:DOWNWARD-FUNARG
decls in the Symbolics implementations. In the function with the &REST arg,
that arg could be declared DOWNWARD meaning that pointers to it and top-level
CDRS are not stored upward and/or it could be declared NO-SETF meaning that
none of the structure (top-level or otherwise) is modified. The intention
here is that the function not mdify part of the &REST arg because it is part
of that arg---the function's contract (documentation) could specify that some
other structure might be modified and if part of that structure is shared by
the &REST parameter, then caveat caller as usual. On the call to apply, the
last argument could be declared to be SMASHABLE and/or SHARABLE when it is
and/or compiler optimizers can detect when the list is freshly consed or a
quote etc. Apply could decide whether to pass the original, stack cons,
or heap cons as appropriate. When in doubt, it would always do the latter.
∂16-Mar-88 1754 Common-Lisp-mailer &rest args -- (declarations)
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 16 Mar 88 17:53:58 PST
Posted-Date: Wed, 16 Mar 88 15:17:23 PST
Message-Id: <8803162317.AA14565@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA14565; Wed, 16 Mar 88 15:17:27 PST
To: common-lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: &rest args -- (declarations)
Date: Wed, 16 Mar 88 15:17:23 PST
Sender: goldman@vaxa.isi.edu
Has consideration been given to providing at least some declaration(s) the
programmer can make -- e.g.,
(DEFUN FOO (&REST L) (DECLARE (DYNAMIC-EXTENT L) (READ-ONLY L)) ...)
that would effectively AUTHORIZE a compiler to perform certain
optimizations/transformations even when it could NOT otherwise PROVE the
optimization/transformation preserved equivalence?
[At least one implementation already provides a similar declaration
for functional arguments, that authorizes the "consing" of
lexical closures on the stack.]
There is no doubt some latitude for choosing relevant declarations. I'm
NOT proposing a particular set here in the hope that the matter has already
been given more thought by someone else. Has it?
neil
∂17-Mar-88 0511 Common-Lisp-mailer &REST args
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 17 Mar 88 05:11:18 PST
Received: from WINTER.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 179199; Thu 17-Mar-88 07:47:51 EST
Date: Thu, 17 Mar 88 00:38 EST
From: Charles Hornig <Hornig@ALDERAAN.SCRC.Symbolics.COM>
Subject: &REST args
To: Jeff Barnett <jbarnett@nrtc.northrop.com>, goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: The message of 16 Mar 88 18:35 EST from Jeff Barnett <jbarnett@nrtc.northrop.com>,
<8803162317.AA14565@vaxa.isi.edu>
Message-ID: <19880317053813.3.HORNIG@WINTER.SCRC.Symbolics.COM>
Yes, declarations would be a good thing if we decide that Common Lisp
permits valid programs to store pointers to or to destructively modify
&REST arguments. If we decide that Common Lisp does not permit it, or
leaves the result undefined (which is another way of saying the same
thing), then there is no need for declarations.
I believe that there is general agreement that one is allowed to save
pointers to &REST arguments. There seems to be no agreement about
destructive modification. I, personally, believe that destructive
modification should be permitted and that the language implementation
must guarantee that this will not currupt structures passed as APPLY
arguments. This guarantee can be done through declarations, code
analysis, or just consing a lot.
∂18-Mar-88 1444 Common-Lisp-mailer &REST args
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 18 Mar 88 14:44:08 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 18 Mar 88 17:45-EST
Received: from JASPER.Palladian.COM (JASPER.Palladian.COM) by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 84701; 18 Mar 88 17:35:44-EST
Received: from KITTYHAWK.Palladian.COM by JASPER.Palladian.COM via CHAOS with CHAOS-MAIL id 27421; Fri 18-Mar-88 17:30:36 EST
Date: Fri, 18 Mar 88 17:30 EST
From: K. Shane Hartman <Shane@JASPER.Palladian.COM>
Subject: &REST args
To: jbarnett@nrtc.northrop.com
cc: common-lisp@sail.stanford.edu
In-Reply-To: The message of 16 Mar 88 18:35 EST from Jeff Barnett <jbarnett@nrtc.northrop.com>
Message-ID: <880318173025.0.SHANE@KITTYHAWK.Palladian.COM>
Date: Wed, 16 Mar 88 15:35:28 PST
From: Jeff Barnett <jbarnett@nrtc.northrop.com>
In regards to the properties of &REST arguments: There may be a way to
have our cake and eat it too given that CL has a declaration mechanism
in place already and optimization hints are considered first class citizens.
I propose an anology to the SYS:DOWNWARD-FUNCTION and SYS:DOWNWARD-FUNARG
decls in the Symbolics implementations. In the function with the &REST arg,
that arg could be declared DOWNWARD meaning that pointers to it and top-level
Lucid uses the declaration DYNAMIC-EXTENT for this purpose.
-[Shane]->
∂19-Mar-88 0055 Common-Lisp-mailer &REST args
Received: from elroy.Jpl.Nasa.Gov by SAIL.Stanford.EDU with TCP; 19 Mar 88 00:52:48 PST
Received: by elroy.Jpl.Nasa.Gov (4.0/SMI-3.2+DXR)
id AA04650; Fri, 18 Mar 88 19:34:53 PST
Received: by grian.cps.com (3.2/SMI-3.2)
id AA06610; Fri, 18 Mar 88 18:34:19 PST
To: cps-common
Path: grian!uucp
From: K. Shane Hartman <grian!elroy!Shane%JASPER.Palladian.COM@elroy.Jpl.Nasa.Gov>
Newsgroups: cps.common
Subject: &REST args
Message-Id: <450@grian.UUCP>
Date: 19 Mar 88 02:34:17 GMT
Sender: grian!uucp@elroy.Jpl.Nasa.Gov
Lines: 16
Date: Wed, 16 Mar 88 15:35:28 PST
From: Jeff Barnett <jbarnett@nrtc.northrop.com>
In regards to the properties of &REST arguments: There may be a way to
have our cake and eat it too given that CL has a declaration mechanism
in place already and optimization hints are considered first class citizens.
I propose an anology to the SYS:DOWNWARD-FUNCTION and SYS:DOWNWARD-FUNARG
decls in the Symbolics implementations. In the function with the &REST arg,
that arg could be declared DOWNWARD meaning that pointers to it and top-level
Lucid uses the declaration DYNAMIC-EXTENT for this purpose.
-[Shane]->
∂19-Mar-88 0156 Common-Lisp-mailer &rest lists and other things ground through function application
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 19 Mar 88 01:56:20 PST
Return-Path: <barmar@Think.COM>
Received: from pozzo.think.com by Think.COM; Sat, 19 Mar 88 04:55:44 EST
Received: by pozzo.think.com; Sat, 19 Mar 88 04:55:38 est
Date: Sat, 19 Mar 88 04:55:38 est
From: Barry Margolin <barmar@Think.COM>
Message-Id: <8803190955.AA09901@pozzo.think.com>
To: mcvax!pilatus!ceb@uunet.uu.net
Cc: common-lisp@sail.stanford.edu
In-Reply-To: mcvax!pilatus!ceb@uunet.uu.net's message of Sun, 13 Mar 88 13:22:44 +0100 <8803131222.AA20860@cernvax.uucp>
Subject: &rest lists and other things ground through function application
From: mcvax!pilatus!ceb@uunet.uu.net
Date: Sun, 13 Mar 88 13:22:44 +0100
If you want to be able to freely modify the structures which are
used to implement these features, something imbedded in the kernel of
the language is going to have to *copy* them.
You could do a top-level copy, but then you are still not protected if
someone does a (setf (cadr passed-argument-structure 'truc). In order
to beat this, you have to do an arbitrary depth copy, and then, when
you pass tangled, circular, non-ending horrible things which make
print go bananas (I do this often), you have to do circular list
detection, etc. . . . and you very quickly get into a game which can't
be won.
While this is true, it is not really significant. In the case of the
substructure, this is no different from ordinary arguments - the Nth
parameter seen by a function is always EQL to the Nth argument passed
to the function. &REST lists, however, have the additional potential
for being EQ with the list passed as the last argument to APPLY, and
this is what needs to be specified more carefully.
barmar
∂19-Mar-88 1153 Common-Lisp-mailer &rest lists and other things ground through function application
Received: from elroy.Jpl.Nasa.Gov by SAIL.Stanford.EDU with TCP; 19 Mar 88 11:52:08 PST
Received: by elroy.Jpl.Nasa.Gov (4.0/SMI-3.2+DXR)
id AA07184; Sat, 19 Mar 88 04:33:48 PST
Received: by grian.cps.com (3.2/SMI-3.2)
id AA08488; Sat, 19 Mar 88 03:38:28 PST
To: cps-common
Path: grian!uucp
From: Barry Margolin <grian!elroy!barmar%Think.COM@elroy.Jpl.Nasa.Gov>
Newsgroups: cps.common
Subject: &rest lists and other things ground through function application
Message-Id: <454@grian.UUCP>
Date: 19 Mar 88 11:38:26 GMT
Sender: grian!uucp@elroy.Jpl.Nasa.Gov
Lines: 24
From: mcvax!pilatus!ceb@uunet.uu.net
Date: Sun, 13 Mar 88 13:22:44 +0100
If you want to be able to freely modify the structures which are
used to implement these features, something imbedded in the kernel of
the language is going to have to *copy* them.
You could do a top-level copy, but then you are still not protected if
someone does a (setf (cadr passed-argument-structure 'truc). In order
to beat this, you have to do an arbitrary depth copy, and then, when
you pass tangled, circular, non-ending horrible things which make
print go bananas (I do this often), you have to do circular list
detection, etc. . . . and you very quickly get into a game which can't
be won.
While this is true, it is not really significant. In the case of the
substructure, this is no different from ordinary arguments - the Nth
parameter seen by a function is always EQL to the Nth argument passed
to the function. &REST lists, however, have the additional potential
for being EQ with the list passed as the last argument to APPLY, and
this is what needs to be specified more carefully.
barmar
∂19-Mar-88 1154 Common-Lisp-mailer &REST args
Received: from elroy.Jpl.Nasa.Gov by SAIL.Stanford.EDU with TCP; 19 Mar 88 11:54:06 PST
Received: by elroy.Jpl.Nasa.Gov (4.0/SMI-3.2+DXR)
id AA06784; Sat, 19 Mar 88 03:38:42 PST
Received: by grian.cps.com (3.2/SMI-3.2)
id AA08302; Sat, 19 Mar 88 02:41:02 PST
To: cps-common
Path: grian!uucp
From: K. Shane Hartman <grian!elroy!grian!elroy!Shane%JASPER.Palladian.COM@elroy.Jpl.Nasa.Gov>
Newsgroups: cps.common
Subject: &REST args
Message-Id: <453@grian.UUCP>
Date: 19 Mar 88 10:40:58 GMT
Sender: grian!uucp@elroy.Jpl.Nasa.Gov
Lines: 17
Date: Wed, 16 Mar 88 15:35:28 PST
From: Jeff Barnett <jbarnett@nrtc.northrop.com>
In regards to the properties of &REST arguments: There may be a way to
have our cake and eat it too given that CL has a declaration mechanism
in place already and optimization hints are considered first class citizens.
I propose an anology to the SYS:DOWNWARD-FUNCTION and SYS:DOWNWARD-FUNARG
decls in the Symbolics implementations. In the function with the &REST arg,
that arg could be declared DOWNWARD meaning that pointers to it and top-level
Lucid uses the declaration DYNAMIC-EXTENT for this purpose.
-[Shane]->
∂19-Mar-88 1404 Common-Lisp-mailer &REST args
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 19 Mar 88 14:04:29 PST
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 366372; Sat 19-Mar-88 17:04:33 EST
Date: Sat, 19 Mar 88 17:04 EST
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: &REST args
To: Charles Hornig <Hornig@ALDERAAN.SCRC.Symbolics.COM>, Jeff Barnett <jbarnett@nrtc.northrop.com>,
goldman@vaxa.isi.edu, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880317053813.3.HORNIG@WINTER.SCRC.Symbolics.COM>
Message-ID: <19880319220430.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Thu, 17 Mar 88 00:38 EST
From: Charles Hornig <Hornig@ALDERAAN.SCRC.Symbolics.COM>
Yes, declarations would be a good thing if we decide that Common Lisp
permits valid programs to store pointers to or to destructively modify
&REST arguments. If we decide that Common Lisp does not permit it, or
leaves the result undefined (which is another way of saying the same
thing), then there is no need for declarations.
Agreed.
I believe that there is general agreement that one is allowed to save
pointers to &REST arguments.
Agreed.
There seems to be no agreement about destructive modification.
The X3J13 Cleanup subcommittee has taken on this issue. We discussed
it at a meeting on Tuesday and will be discussing it further. It's likely
that X3J13 will make a decision on this issue in June. Of course, nothing
X3J13 decides is final until a language specification is created, accepted
by written ballot, and reported out of the X3J13 committee to the parent
standards organizations.
I, personally, believe that destructive
modification should be permitted and that the language implementation
must guarantee that this will not currupt structures passed as APPLY
arguments. This guarantee can be done through declarations, code
analysis, or just consing a lot.
For the record, I strongly disagree with this. I believe Common Lisp should
specify that the value of an &REST parameter is permitted, but not required,
to share structure with the last argument to APPLY. I have two reasons for
this belief (both of which have come up on the mailing list before).
1. In no other place does Common Lisp automatically unshare structure,
except when the user is explicitly modifying the structure (as in REMOVE).
Making APPLY automatically unshare would be a semantic wart.
2. If APPLY copies its last argument, recursive programs that receive an
&REST argument and pass it to APPLY become inefficient. A linear time
algorithm can change to a quadratic time algorithm. While the efficiency
could be regained through compiler flow analysis in many cases, I think
it's better not to put the inefficiency into the language in the first
place.
∂19-Mar-88 2304 Common-Lisp-mailer &rest lists should not be copied
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 19 Mar 88 23:04:34 PST
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA07506; Sun, 20 Mar 88 02:05:03 EST
From: mcvax!pilatus!ceb@uunet.UU.NET
Received: by mcvax.cwi.nl; Sun, 20 Mar 88 07:49:03 +0100 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA24818; Sun, 20 Mar 88 07:03:27 +0100
Date: Sun, 20 Mar 88 07:03:27 +0100
Message-Id: <8803200603.AA24818@cernvax.uucp>
To: barmar@think.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Sat, 19 Mar 88 04:55:38 est
Subject: &rest lists should not be copied
Date: Sat, 19 Mar 88 04:55:38 est
From: Barry Margolin <cernvax!mcvax!Think.COM!barmar>
From: mcvax!pilatus!ceb@uunet.uu.net
Date: Sun, 13 Mar 88 13:22:44 +0100
If you want to be able to freely modify the structures which are
used to implement these features, something imbedded in the kernel of
the language is going to have to *copy* them.
While this is true, it is not really significant.
. . . &REST lists, however, have the additional potential
for being EQ with the list passed as the last argument to APPLY, and
this is what needs to be specified more carefully.
. . . as they should. What made me write were suggestions that the
*default* behavior be (at least top-level) cons structure copying. I
wanted to demonstrate that this could be potentially expensive, but I
guess it was counter-productive to draw in the issue of lower-level
copying. Anyhow, even enforcing only top-level copying, even if you
restrict yourself to rest lists of "reasonable" size, can cost many
conses, and should not be forced upon you. Assuming both
kinds of behavior are desirable; one only should ask:
1. Which one should be the default?
2. How do you specify your choice?
A number have written drawing attention to existing or proposed
(mainly declare) forms to accomplish this. As I understand these
though, I don't like them because:
1. The default behavior is copying, the more expensive of the two.
2, If the default behavior were not to copy, it would not cost much
if at all more to ask for copying explicitly with a (let . . .
(copy-list <rest-arg-list>) construct. Burying such stuff away in
the guts of a language only bring about over-use. On the other
hand, explicit mention has positive effects on user optimization.
3. One should avoid fueling the "there's too much junk in common-lisp"
fire whenever possible.
4. Declare forms are reminiscent of other programming languages I
switched *from* to come to Lisp. I accept them as means for
advising the compiler to obtain faster compiled code, as long as I can
safely ignore them when rapid prototyping. However, at issue here
is averting potentially incorrect behavior (I include cancer-like
consing in this), regardless of whether you run interpreted or compiled.
About the only real efficiency argument I have been able to drum up
for intervening at the moment of function invocation (as opposed to
within the called function body) is that stack consing might be
cheaper than general consing (even if you cdr code?). If this is
really a consideration, then why not simply add keywords to apply and
friends, such as :stack-copy-args and/or :copy-args, with defaults set
up reasonably?
This would keep all of the strangeness in source code *and* and in
the compiler localized to the trouble point (within apply).
ceb
∂21-Mar-88 0810 Common-Lisp-mailer CLOS Status
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 21 Mar 88 08:10:16 PST
Received: from Riesling.ms by ArpaGateway.ms ; 21 MAR 88 08:08:22 PST
Sender: "James_L_Mayer.WBST128"@Xerox.COM
Date: 21 Mar 88 08:07:13 PST (Monday)
Subject: CLOS Status
From: "James_L_Mayer.WBST128"@Xerox.COM
To: Common-Lisp@SAIL.STANFORD.EDU
cc: Common-Lisp-Object-System@SAIL.STANFORD.EDU
Reply-to: "James_L_Mayer.WBST128"@Xerox.COM
Message-ID: <880321-080822-3332@Xerox>
Some questions about the Common Lisp Object System:
(1) What is the status of the standard? When was the last draft spec released
and how can I get a copy?
(2) What is the implementation status? Is PCL still the best approximation
available?
(3) I will be running in Sun Common Lisp. What CLOS options are/will be open to
me?
Thank you.
-- Jim Mayer
∂23-Mar-88 1313 Common-Lisp-mailer &Rest Lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 23 Mar 88 13:13:10 PST
Received: from relay2.cs.net by RELAY.CS.NET id ai11131; 23 Mar 88 15:12 EST
Received: from cs.umass.edu by RELAY.CS.NET id ah11782; 23 Mar 88 15:03 EST
Date: Wed, 23 Mar 88 12:50 EDT
From: ELIOT@cs.umass.edu
Subject: &Rest Lists
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"Moon@SCRC-STONY-BROOK.ARPA" "David A. Moon" 20-MAR-1988 08:07
Subj: &REST args
For the record, I strongly disagree with this. I believe Common Lisp should
specify that the value of an &REST parameter is permitted, but not required,
to share structure with the last argument to APPLY. I have two reasons for
this belief (both of which have come up on the mailing list before).
I disagree with this. As I stated in an earlier message I think that Common
Lisp should prohibit sharing of list structure in the last argument
to APPLY.
1. In no other place does Common Lisp automatically unshare structure,
except when the user is explicitly modifying the structure (as in REMOVE).
Making APPLY automatically unshare would be a semantic wart.
Common Lisp does commit itself to doing whatever has to be done so that
interpreted and compiled code behaves the same. Actually I don't care
whether that last argument to APPLY can be shared. But I stongly
believe that Common Lisp should do whatever has to be done so that
all variants of the same function call are equivalent. Consider:
(setq x '(1 2 3))
[1] (apply #'foo 1 2 3 NIL)
[2] (apply #'foo 1 2 (cddr x))
[3] (apply #'foo 1 (cdr x))
[4] (apply #'foo x)
[5] (funcall #'foo 1 2 3)
[6] (eval (cons 'foo x))
[7] (eval (list 'foo 1 2 3))
[8] (foo 1 2 3)
I strongly believe that all of [1-8] are the same function call and
must have the same semantics. Since the list, x, cannot be modified by
[1, 5, 7, 8] it should not be allowed to modify it in [2, 3, 4, 6].
2. If APPLY copies its last argument, recursive programs that receive an
&REST argument and pass it to APPLY become inefficient. A linear time
algorithm can change to a quadratic time algorithm. While the efficiency
could be regained through compiler flow analysis in many cases, I think
it's better not to put the inefficiency into the language in the first
place.
Using APPLY is probably inefficient anyhow. If this kind of recursive
function has to run quickly it would probably be better to define an
auxillary function with a fixed number of arguments to do the real work.
Besides, most function calls are not made using APPLY. Recursive
function calls using APPLY are too rare to justify a blemish in the
semantics of all function calls.
Common Lisp already has a large number of undefined cases. I don't
think that a possible minor optimization of a special case of using
APPLY is sufficiently important to justify allowing any ambiguity in the
semantics of &Rest lists. Especially since it is acknowledged that a
good compiler can probably implement the unambiguous semantics equally
efficiently.
Some might argue that the correct way to disambiguate this situation is
to specify that APPLY must share its final argument with any &Rest list
argument as much as possible. This doesn't make sense to me. I don't
believe that it would make Common Lisp more efficient to any significant
degree. I think it creates an undesirable inconsistency in the
semantics of function calls, as I argued above. Furthermore, modifying
&Rest lists as a way to indirectly modify some argument to APPLY sounds
like one of the worst dirty programming tricks I have heard of in a long
time. The possibility of causing exceedingly obscure bugs makes my skin
crawl.
∂23-Mar-88 1731 Common-Lisp-mailer &Rest Lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 23 Mar 88 17:31:21 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 23 Mar 88 20:30:47 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 23 Mar 88 20:30:43 EST
Date: Wed, 23 Mar 88 20:31 EST
From: Barry Margolin <barmar@Think.COM>
Subject: &Rest Lists
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8803232113.AA02705@Think.COM>
Message-Id: <19880324013118.3.BARMAR@OCCAM.THINK.COM>
Date: Wed, 23 Mar 88 12:50 EDT
From: ELIOT@cs.umass.edu
From: IN%"Moon@SCRC-STONY-BROOK.ARPA" "David A. Moon" 20-MAR-1988 08:07
Subj: &REST args
As I stated in an earlier message I think that Common
Lisp should prohibit sharing of list structure in the last argument
to APPLY.
1. In no other place does Common Lisp automatically unshare structure,
except when the user is explicitly modifying the structure (as in REMOVE).
Making APPLY automatically unshare would be a semantic wart.
Common Lisp does commit itself to doing whatever has to be done so that
interpreted and compiled code behaves the same.
How did the compiler/interpreter distinction enter into this? No one
has proposed distinguishing them. In the environment I use, they both
behave the same regarding &rest lists. And even so, the compiler and
interpreter are allowed to have different ways of dealing with a
situation that is undefined ("is an error", to use CLtL wording),
because portable applications are not permitted to depend on the
behavior in such situations.
Actually I don't care
whether that last argument to APPLY can be shared. But I stongly
believe that Common Lisp should do whatever has to be done so that
all variants of the same function call are equivalent. Consider:
(setq x '(1 2 3))
[1] (apply #'foo 1 2 3 NIL)
[2] (apply #'foo 1 2 (cddr x))
[3] (apply #'foo 1 (cdr x))
[4] (apply #'foo x)
[5] (funcall #'foo 1 2 3)
[6] (eval (cons 'foo x))
[7] (eval (list 'foo 1 2 3))
[8] (foo 1 2 3)
I strongly believe that all of [1-8] are the same function call and
must have the same semantics. Since the list, x, cannot be modified by
[1, 5, 7, 8] it should not be allowed to modify it in [2, 3, 4, 6].
I disagree with this. [5, 7, 8] don't even reference the list x, so how
can they be considered the same? And the difference between [4] and [6]
would be quite obvious if any of the elements of x were objects that
don't self-evaluate, e.g.:
(setq a 1 b 2 c 3 x '(a b c))
(apply #'list x) => (a b c) (which, by the way, should not share
structure with x)
(eval (cons 'list x)) => (1 2 3)
2. If APPLY copies its last argument, recursive programs that receive an
&REST argument and pass it to APPLY become inefficient. A linear time
algorithm can change to a quadratic time algorithm. While the efficiency
could be regained through compiler flow analysis in many cases, I think
it's better not to put the inefficiency into the language in the first
place.
Using APPLY is probably inefficient anyhow.
I sure hope not! Many implementations of EVAL use APPLY internally for
all function calls, something along the lines of:
(apply (symbol-function (car form)) (mapcar #'eval (cdr form)))
(yes, this is extremely simplified, I know that the real thing is much
more complex).
If this kind of recursive
function has to run quickly it would probably be better to define an
auxillary function with a fixed number of arguments to do the real work.
Besides, most function calls are not made using APPLY. Recursive
function calls using APPLY are too rare to justify a blemish in the
semantics of all function calls.
It's not just recursive calls. Consider all the functions that take
arguments just like FORMAT. They all call various intermediate
functions, which call other intermediates, and eventually they call
FORMAT itself. The &rest list shouldn't be duplicated at each call.
Many other functions take &rest arguments that are simply passed on to
other functions using APPLY.
Some might argue that the correct way to disambiguate this situation is
to specify that APPLY must share its final argument with any &Rest list
argument as much as possible. This doesn't make sense to me. I don't
believe that it would make Common Lisp more efficient to any significant
degree. I think it creates an undesirable inconsistency in the
semantics of function calls, as I argued above. Furthermore, modifying
&Rest lists as a way to indirectly modify some argument to APPLY sounds
like one of the worst dirty programming tricks I have heard of in a long
time. The possibility of causing exceedingly obscure bugs makes my skin
crawl.
I don't think anyone is actually suggesting that people intentionally
modify &rest lists. Personally, I prefer making it be undefined whether
&rest lists share, so programmers aren't tempted to write such code.
barmar
∂23-Mar-88 1830 Common-Lisp-mailer &Rest Lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 23 Mar 88 17:31:21 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 23 Mar 88 20:30:47 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 23 Mar 88 20:30:43 EST
Date: Wed, 23 Mar 88 20:31 EST
From: Barry Margolin <barmar@Think.COM>
Subject: &Rest Lists
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8803232113.AA02705@Think.COM>
Message-Id: <19880324013118.3.BARMAR@OCCAM.THINK.COM>
Date: Wed, 23 Mar 88 12:50 EDT
From: ELIOT@cs.umass.edu
From: IN%"Moon@SCRC-STONY-BROOK.ARPA" "David A. Moon" 20-MAR-1988 08:07
Subj: &REST args
As I stated in an earlier message I think that Common
Lisp should prohibit sharing of list structure in the last argument
to APPLY.
1. In no other place does Common Lisp automatically unshare structure,
except when the user is explicitly modifying the structure (as in REMOVE).
Making APPLY automatically unshare would be a semantic wart.
Common Lisp does commit itself to doing whatever has to be done so that
interpreted and compiled code behaves the same.
How did the compiler/interpreter distinction enter into this? No one
has proposed distinguishing them. In the environment I use, they both
behave the same regarding &rest lists. And even so, the compiler and
interpreter are allowed to have different ways of dealing with a
situation that is undefined ("is an error", to use CLtL wording),
because portable applications are not permitted to depend on the
behavior in such situations.
Actually I don't care
whether that last argument to APPLY can be shared. But I stongly
believe that Common Lisp should do whatever has to be done so that
all variants of the same function call are equivalent. Consider:
(setq x '(1 2 3))
[1] (apply #'foo 1 2 3 NIL)
[2] (apply #'foo 1 2 (cddr x))
[3] (apply #'foo 1 (cdr x))
[4] (apply #'foo x)
[5] (funcall #'foo 1 2 3)
[6] (eval (cons 'foo x))
[7] (eval (list 'foo 1 2 3))
[8] (foo 1 2 3)
I strongly believe that all of [1-8] are the same function call and
must have the same semantics. Since the list, x, cannot be modified by
[1, 5, 7, 8] it should not be allowed to modify it in [2, 3, 4, 6].
I disagree with this. [5, 7, 8] don't even reference the list x, so how
can they be considered the same? And the difference between [4] and [6]
would be quite obvious if any of the elements of x were objects that
don't self-evaluate, e.g.:
(setq a 1 b 2 c 3 x '(a b c))
(apply #'list x) => (a b c) (which, by the way, should not share
structure with x)
(eval (cons 'list x)) => (1 2 3)
2. If APPLY copies its last argument, recursive programs that receive an
&REST argument and pass it to APPLY become inefficient. A linear time
algorithm can change to a quadratic time algorithm. While the efficiency
could be regained through compiler flow analysis in many cases, I think
it's better not to put the inefficiency into the language in the first
place.
Using APPLY is probably inefficient anyhow.
I sure hope not! Many implementations of EVAL use APPLY internally for
all function calls, something along the lines of:
(apply (symbol-function (car form)) (mapcar #'eval (cdr form)))
(yes, this is extremely simplified, I know that the real thing is much
more complex).
If this kind of recursive
function has to run quickly it would probably be better to define an
auxillary function with a fixed number of arguments to do the real work.
Besides, most function calls are not made using APPLY. Recursive
function calls using APPLY are too rare to justify a blemish in the
semantics of all function calls.
It's not just recursive calls. Consider all the functions that take
arguments just like FORMAT. They all call various intermediate
functions, which call other intermediates, and eventually they call
FORMAT itself. The &rest list shouldn't be duplicated at each call.
Many other functions take &rest arguments that are simply passed on to
other functions using APPLY.
Some might argue that the correct way to disambiguate this situation is
to specify that APPLY must share its final argument with any &Rest list
argument as much as possible. This doesn't make sense to me. I don't
believe that it would make Common Lisp more efficient to any significant
degree. I think it creates an undesirable inconsistency in the
semantics of function calls, as I argued above. Furthermore, modifying
&Rest lists as a way to indirectly modify some argument to APPLY sounds
like one of the worst dirty programming tricks I have heard of in a long
time. The possibility of causing exceedingly obscure bugs makes my skin
crawl.
I don't think anyone is actually suggesting that people intentionally
modify &rest lists. Personally, I prefer making it be undefined whether
&rest lists share, so programmers aren't tempted to write such code.
barmar
∂24-Mar-88 0930 Common-Lisp-mailer &REST Lists
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 24 Mar 88 09:30:25 PST
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA15797@EDDIE.MIT.EDU>; Thu, 24 Mar 88 12:28:18 EST
Received: by spt.entity.com (smail2.5); 24 Mar 88 12:23:15 EST (Thu)
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST Lists
Message-Id: <8803241223.AA05234@spt.entity.com>
Date: 24 Mar 88 12:23:15 EST (Thu)
From: gz@spt.entity.com (Gail Zacharias)
I don't think requiring &rest lists to be (conceptually) freshly consed is
somehow "automatically unsharing" structure. It depends on how you see the
semantics of function calling - I think a function gets a certain number of
individual arguments, and &REST requests that some of those arguments be
constructed into a list. It's all internal to the function and nobody else's
business. APPLY's contract is to pass *elements* of a list to a function as
arguments. From this point of view, having a list given to APPLY suddenly
show up inside some function, without being passed as an argument to that
function, is not a natural case of sharing -- it's a case of unexpected
collapsing of equal structures, not that much different from, say,
(eq (union (list 'a) (list 'b)) (union (list 'a) (list 'b))) ==> T.
On the practical side, there is an idiom that occurs in almost every
non-trivial portable common lisp program I've seen, which looks something like
this:
(DEFUN FN (&REST FOO)
#+<systems known to not cons &rest args> (SETQ FOO (COPY-LIST FOO))
...)
or sometimes just like this:
(DEFUN FN (&REST FOO) (SETQ FOO (COPY-LIST FOO)) ...)
For example, a quick scan through PCL (it happened to be handy) finds at least
5 instances of this idiom, 2 with the conditionalization and 3 without. The
COPY-LIST is of course wasteful in implementations which guarantee no
user-visible sharing of &rest lists, but it is also wasteful in the
APPLY/&REST-optimizing implementations when the function is being called
normally (i.e. with no handy pre-consed arg list to reuse), which is usually
most of the time. If Common Lisp doesn't require unshared &rest lists, then I
think it must provide a declarative version of this idiom so the COPY-LIST can
be portably avoided when it's redundant. Seems to me that the fact that this
is a common case where users find a need for conditionalization indicates a
real deficiency in Common Lisp's specification.
Regarding the case of a format-like function applying a format-like function
and so on, wouldn't it be cleaner and even more efficient to provide some
special construct for that case, such as (off the top of my head) a RE-APPLY,
which would request the caller's args to be passed on to the callee? (And
wasn't somebody working on designing an &MORE or some such abstraction which
avoided consing altogether? Whatever happened to that?)
∂24-Mar-88 0952 Common-Lisp-mailer &REST Lists
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 24 Mar 88 09:30:25 PST
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA15797@EDDIE.MIT.EDU>; Thu, 24 Mar 88 12:28:18 EST
Received: by spt.entity.com (smail2.5); 24 Mar 88 12:23:15 EST (Thu)
To: common-lisp@SAIL.STANFORD.EDU
Subject: &REST Lists
Message-Id: <8803241223.AA05234@spt.entity.com>
Date: 24 Mar 88 12:23:15 EST (Thu)
From: gz@spt.entity.com (Gail Zacharias)
I don't think requiring &rest lists to be (conceptually) freshly consed is
somehow "automatically unsharing" structure. It depends on how you see the
semantics of function calling - I think a function gets a certain number of
individual arguments, and &REST requests that some of those arguments be
constructed into a list. It's all internal to the function and nobody else's
business. APPLY's contract is to pass *elements* of a list to a function as
arguments. From this point of view, having a list given to APPLY suddenly
show up inside some function, without being passed as an argument to that
function, is not a natural case of sharing -- it's a case of unexpected
collapsing of equal structures, not that much different from, say,
(eq (union (list 'a) (list 'b)) (union (list 'a) (list 'b))) ==> T.
On the practical side, there is an idiom that occurs in almost every
non-trivial portable common lisp program I've seen, which looks something like
this:
(DEFUN FN (&REST FOO)
#+<systems known to not cons &rest args> (SETQ FOO (COPY-LIST FOO))
...)
or sometimes just like this:
(DEFUN FN (&REST FOO) (SETQ FOO (COPY-LIST FOO)) ...)
For example, a quick scan through PCL (it happened to be handy) finds at least
5 instances of this idiom, 2 with the conditionalization and 3 without. The
COPY-LIST is of course wasteful in implementations which guarantee no
user-visible sharing of &rest lists, but it is also wasteful in the
APPLY/&REST-optimizing implementations when the function is being called
normally (i.e. with no handy pre-consed arg list to reuse), which is usually
most of the time. If Common Lisp doesn't require unshared &rest lists, then I
think it must provide a declarative version of this idiom so the COPY-LIST can
be portably avoided when it's redundant. Seems to me that the fact that this
is a common case where users find a need for conditionalization indicates a
real deficiency in Common Lisp's specification.
Regarding the case of a format-like function applying a format-like function
and so on, wouldn't it be cleaner and even more efficient to provide some
special construct for that case, such as (off the top of my head) a RE-APPLY,
which would request the caller's args to be passed on to the callee? (And
wasn't somebody working on designing an &MORE or some such abstraction which
avoided consing altogether? Whatever happened to that?)
∂24-Mar-88 2246 Common-Lisp-mailer &Rest Lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 24 Mar 88 22:46:07 PST
Received: from relay2.cs.net by RELAY.CS.NET id ab04582; 25 Mar 88 1:26 EST
Received: from cs.umass.edu by RELAY.CS.NET id aq23262; 25 Mar 88 1:10 EST
Date: Thu, 24 Mar 88 17:12 EDT
From: ELIOT@cs.umass.edu
Subject: &Rest Lists
To: Common-Lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"Common-Lisp@sail.stanford.edu"
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
Common Lisp does commit itself to doing whatever has to be done so that
interpreted and compiled code behaves the same.
How did the compiler/interpreter distinction enter into this? No one
has proposed distinguishing them.
I was using an analogy to try to clarify my line of reasoning. I am not
saying that Common Lisp should actually specify that APPLY copy the list
structure in its final argument, but I am saying that this may be
required in order to correctly implement the semantics that I fell APPLY
should have. Good compilers are free to implement APPLY so that it
shares list structure as long as it does not affect the semantics.
Calls to any function which provably does not modify its &Rest lists
could be implemented more efficiently by such a compiler.
Consider :
(setq x '(1 2 3))
[1] (apply #'foo 1 2 3 NIL)
[2] (apply #'foo 1 2 (cddr x))
[3] (apply #'foo 1 (cdr x))
[4] (apply #'foo x)
[5] (funcall #'foo 1 2 3)
[6] (eval (cons 'foo x))
[7] (eval (list 'foo 1 2 3))
[8] (foo 1 2 3)
I strongly believe that all of [1-8] are the same function call and
must have the same semantics. Since the list, x, cannot be modified by
[1, 5, 7, 8] it should not be allowed to modify it in [2, 3, 4, 6].
I disagree with this. [5, 7, 8] don't even reference the list x, so how
can they be considered the same?
Ignore what happened before the actual function call to FOO. At the
moment FOO actually is called all of its arguments are EQ in all of
these cases. Obviously, my intuituiton is that a function call should
be completely defined by its arguments but not by the computation that
produced them. And I believe that the function call makes explicit what
constitutes a distinct "argument", regardless of the function
definition. Consequently I think that "&Rest x" means that x is a list
of the rest of the argumentS - (plural). In other words the argumentS
that are collected into an &Rest list are totally distinct.
And the difference between [4] and [6]
would be quite obvious if any of the elements of x were objects that
don't self-evaluate, e.g.:
(setq a 1 b 2 c 3 x '(a b c))
(apply #'list x) => (a b c) (which, by the way, should not share
structure with x)
(eval (cons 'list x)) => (1 2 3)
2. If APPLY copies its last argument, recursive programs that receive an
&REST argument and pass it to APPLY become inefficient. A linear time
algorithm can change to a quadratic time algorithm. While the efficiency
could be regained through compiler flow analysis in many cases, I think
it's better not to put the inefficiency into the language in the first
place.
Using APPLY is probably inefficient anyhow.
I sure hope not! Many implementations of EVAL use APPLY internally for
all function calls, something along the lines of:
(apply (symbol-function (car form)) (mapcar #'eval (cdr form)))
(yes, this is extremely simplified, I know that the real thing is much
more complex).
This only applies to interpreted code, not compiled code. And a real
interpreter can be written using implementation dependant primitives,
so the defined Common Lisp behavior of APPLY has nothing to do with
the real efficiency of anything except explicit calls to APPLY.
Certainly normal function calls need not be effected.
What I mean by saying that "Using APPLY is probably inefficient
anyhow" is that you will incur the overhead of a full extra function
call that probably cannot be optimized away. Truly efficient code
requires modifying the arguments so that the list is passed directly,
rather than using &Rest lists, so you can eliminate the function call
involved in using APPLY.
If this kind of recursive
function has to run quickly it would probably be better to define an
auxillary function with a fixed number of arguments to do the real work.
Besides, most function calls are not made using APPLY. Recursive
function calls using APPLY are too rare to justify a blemish in the
semantics of all function calls.
It's not just recursive calls. Consider all the functions that take
arguments just like FORMAT. They all call various intermediate
functions, which call other intermediates, and eventually they call
FORMAT itself. The &rest list shouldn't be duplicated at each call.
Many other functions take &rest arguments that are simply passed on to
other functions using APPLY.
Some might argue that the correct way to disambiguate this situation is
to specify that APPLY must share its final argument with any &Rest list
argument as much as possible. This doesn't make sense to me. I don't
believe that it would make Common Lisp more efficient to any significant
degree. I think it creates an undesirable inconsistency in the
semantics of function calls, as I argued above. Furthermore, modifying
&Rest lists as a way to indirectly modify some argument to APPLY sounds
like one of the worst dirty programming tricks I have heard of in a long
time. The possibility of causing exceedingly obscure bugs makes my skin
crawl.
I don't think anyone is actually suggesting that people intentionally
modify &rest lists. Personally, I prefer making it be undefined whether
&rest lists share, so programmers aren't tempted to write such code.
barmar
I agree that modifying &Rest lists is bad programming style. But I also
think that leaving issues undefined is bad language design, unless there
are very compelling reasons. Compelling reasons include externally
imposed constraints on an implementation (forcing us to live with
ambiguity in the Common Lisp file system operations) and the possibility
of major optimizations on different types of machines. Ambiguity in the
implementation of Arrays allows different types of machines to be used
for efficient CL implementations.
The special case of using APPLY to call a function with an &REST
argument fits neither of these categories. Anything that can be made
more efficient by allowing the last argument of APPLY to be shared as
part of an &Rest list can be implemented MORE efficiently by using a
normal function call directly. For example, you suggest that FORMAT
like functions could not be implemented efficiently. They could be
implemented like this:
(defun format (stream fmt &rest args)
(format-1 stream fmt args))
(defun format-1 (stream fmt args)
...)
(defun errror (fmt &Rest args)
(format-1 *error-io* fmt args)
(call-debugger))
(defun warn (fmt &rest args)
(format-1 *error-io* fmt args)
(when *break-on-warnings* (call-debugger)))
(defun break (fmt &rest args)
(format-1 t fmt args)
(break-loop))
etc.
∂24-Mar-88 2333 Common-Lisp-mailer &Rest Lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 24 Mar 88 23:32:46 PST
Return-Path: <barmar@Think.COM>
Received: from pozzo.think.com by Think.COM; Fri, 25 Mar 88 02:32:10 EST
Received: by pozzo.think.com; Fri, 25 Mar 88 02:32:06 est
Date: Fri, 25 Mar 88 02:32:06 est
From: Barry Margolin <barmar@Think.COM>
Message-Id: <8803250732.AA12798@pozzo.think.com>
To: ELIOT@cs.umass.edu
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Thu, 24 Mar 88 17:12 EDT <8803250647.AA07083@Think.COM>
Subject: &Rest Lists
Date: Thu, 24 Mar 88 17:12 EDT
From: ELIOT@cs.umass.edu
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
What I mean by saying that "Using APPLY is probably inefficient
anyhow" is that you will incur the overhead of a full extra function
call that probably cannot be optimized away. Truly efficient code
requires modifying the arguments so that the list is passed directly,
rather than using &Rest lists, so you can eliminate the function call
involved in using APPLY.
What extra function call? I would hope that the compiler will inline
code calls to APPLY. (apply #'foo '(1 2 3)) should generate code at
least as good as (foo 1 2 3), and the only difference between (apply
#'foo '(1 2 3)) and (apply foo '(1 2 3)) should be whether it extracts
the function from FOO's function or value cell. In the implementation
I use (a Lispm), APPLY is a single instruction. The only extra
inefficiency that APPLY might incur is the one YOU are advocating --
copying its last argument -- which makes your reasoning circular.
If this kind of recursive
function has to run quickly it would probably be better to define an
auxillary function with a fixed number of arguments to do the real work.
Besides, most function calls are not made using APPLY. Recursive
function calls using APPLY are too rare to justify a blemish in the
semantics of all function calls.
Well, I know that I use APPLY a whole lot. Not as often as LIST and
CAR, certainly, but more often than I would have expected.
It's not just recursive calls. Consider all the functions that take
arguments just like FORMAT. They all call various intermediate
functions, which call other intermediates, and eventually they call
FORMAT itself. The &rest list shouldn't be duplicated at each call.
Many other functions take &rest arguments that are simply passed on to
other functions using APPLY.
Some might argue that the correct way to disambiguate this situation is
to specify that APPLY must share its final argument with any &Rest list
argument as much as possible. This doesn't make sense to me. I don't
believe that it would make Common Lisp more efficient to any significant
degree. I think it creates an undesirable inconsistency in the
semantics of function calls, as I argued above. Furthermore, modifying
&Rest lists as a way to indirectly modify some argument to APPLY sounds
like one of the worst dirty programming tricks I have heard of in a long
time. The possibility of causing exceedingly obscure bugs makes my skin
crawl.
I don't think anyone is actually suggesting that people intentionally
modify &rest lists. Personally, I prefer making it be undefined whether
&rest lists share, so programmers aren't tempted to write such code.
barmar
I agree that modifying &Rest lists is bad programming style. But I also
think that leaving issues undefined is bad language design, unless there
are very compelling reasons. Compelling reasons include externally
imposed constraints on an implementation (forcing us to live with
ambiguity in the Common Lisp file system operations) and the possibility
of major optimizations on different types of machines. Ambiguity in the
implementation of Arrays allows different types of machines to be used
for efficient CL implementations.
The special case of using APPLY to call a function with an &REST
argument fits neither of these categories. Anything that can be made
more efficient by allowing the last argument of APPLY to be shared as
part of an &Rest list can be implemented MORE efficiently by using a
normal function call directly. For example, you suggest that FORMAT
like functions could not be implemented efficiently. They could be
implemented like this:
(defun format (stream fmt &rest args)
(format-1 stream fmt args))
(defun format-1 (stream fmt args)
...)
(defun errror (fmt &Rest args)
(format-1 *error-io* fmt args)
(call-debugger))
These solutions only work for built-in functions. Portable code can't
call FORMAT-1. I certainly could make non-&rest versions of my
functions, but this means that I must write two functions when I
previously would have written only one, and if I make all my &rest
functions just invoke the non-&rest versions I also incur an extra
function call (like you thought was inherent in using APPLY).
Also, if you were going to do
(apply #'format str fmt arg2 rest)
and you recoded it to call FORMAT-1, you end up with
(format-1 str fmt (cons arg2 rest))
Actually, this last argument isn't as compelling as I first thought,
because it only reduces efficiency in implementations that cons &rest
lists on the stack, and we've decided that they are violating the
standard by doing this.
I think these are good efficiency justifications for making the
sharing behavior of &rest lists and list given to APPLY be undefined.
barmar
∂29-Mar-88 1951 Common-Lisp-mailer Re: &REST lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 29 Mar 88 19:50:31 PST
Received: from relay2.cs.net by RELAY.CS.NET id ad07769; 29 Mar 88 22:10 EST
Received: from tektronix.tek.com by RELAY.CS.NET id bp04223; 29 Mar 88 22:00 EST
Received: by tektronix.TEK.COM (5.51/6.24)
id AA21206; Tue, 29 Mar 88 13:33:30 PST
Received: by tekchips.CRL.TEK.COM (5.51/6.24)
id AA24417; Tue, 29 Mar 88 13:17:22 PST
Message-Id: <8803292117.AA24417@tekchips.CRL.TEK.COM>
To: common-lisp@SAIL.STANFORD.EDU
Cc: willc@tekchips.crl.tek.com
Subject: Re: &REST lists
Date: 29 Mar 88 13:17:17 PST (Tue)
From: willc%tekchips.CRL@tektronix.tek.com
Page 272 of CLtL, talking about RPLACA and RPLACD, says:
...caution should be exercised when using these functions,
as strange side effects can occur if portions of list
structure become shared.
If APPLY is permitted to side effect its last argument, as advocated
by most participants in the recent discussion, then language similar
to that above should be added to the discussion of APPLY on page 107.
The cautionary language is much more important for APPLY than for
RPLACA and RPLACD because side effects are the whole point of the
latter, but it would be easy for a naive programmer to assume that
APPLY has no gratuitous side effects.
In a recent posting, Eliot Moss revealed that he does not have the
correct model of argument transmission in Common Lisp. He erroneously
believes that CL procedures take sequences of arguments; if this were
the case, one could of course prove that APPLY cannot side effect the
top level of its last argument. Because APPLY can have such side
effects, however, any correct model of CL argument transmission must
have it that at least some CL procedures (those that have a &REST arg)
can accept a linked list (not a sequence) of arguments. If procedures
are to be treated uniformly by the model, then all CL procedures must
accept a linked list of arguments rather than a sequence.
Although this might seem to imply that the CL runtime must cons up
these argument lists for all calls that don't involve APPLY, it happens
that the CL compiler can in practice avoid the consing by observing that
the first operation performed by all procedures except those with &REST
arguments is to take the argument list apart into a sequence; furthermore
there is enough slack in the semantics of procedures with &REST arguments
-- the &REST argument need not share structure with the argument list,
although it may -- that it's ok to avoid the consing even when the compiler
is unable to prove that the procedure being called does not take a &REST
argument.
I think Moss would agree with me that this is a ridiculous model of
argument transmission, but it shows that the semantics advocated by
his opponents can be made consistent.
William Clinger
Semantic Microsystems, Inc.
∂29-Mar-88 2340 Common-Lisp-mailer &Rest Lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 29 Mar 88 23:40:19 PST
Received: from relay2.cs.net by RELAY.CS.NET id ag11003; 30 Mar 88 2:21 EST
Received: from cs.umass.edu by RELAY.CS.NET id bz05482; 30 Mar 88 2:08 EST
Date: Tue, 29 Mar 88 12:12 EDT
From: ELIOT@cs.umass.edu
Subject: &Rest Lists
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
Date: Thu, 24 Mar 88 17:12 EDT
From: ELIOT@cs.umass.edu
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
What I mean by saying that "Using APPLY is probably inefficient
anyhow" is that you will incur the overhead of a full extra function
call that probably cannot be optimized away. ...
What extra function call? I would hope that the compiler will inline
code calls to APPLY. (apply #'foo '(1 2 3)) should generate code at
least as good as (foo 1 2 3), and the only difference between (apply
#'foo '(1 2 3)) and (apply foo '(1 2 3)) should be whether it extracts
the function from FOO's function or value cell. In the implementation
I use (a Lispm), APPLY is a single instruction.
Is it an instruction, or a microcoded subroutine? :-)
The only extra
inefficiency that APPLY might incur is the one YOU are advocating --
copying its last argument -- which makes your reasoning circular.
I looked at both VAXLISP and NIL to see what they do. Both of these
implementations spread the arguments out on the stack in the calling
function and collect them back into a list when entering the function
with the &Rest argument. Consequently they might use stack lists,
but they cannot share list stucture as you are proposing.
A normal function call [i.e. (foo 1 2 3)] gets compiled as a series
of individual PUSHES as the arguments are evaluated. (Equivalently,
memory for the entire set of arguments can be allocated on the stack
and individual values MOVEd into the correct location.)
A function call using APPLY would PUSH the initial arguments and then
call a hand-coded assembly routine to push the rest of the arguments.
Consequently, the state of the stack when FOO is entered is the same
regardless of how FOO gets called, so FOO cannot differentiate
calls moderated by APPLY from normal function calls. Your APPLY
microprogram might do something similar, and it certainly could.
Calls made using APPLY are not specially optimized. However, FOO can
be compiled using full knowledge of the body of FOO. So if FOO does
not return its &Rest list it can be CONSed on the stack. On a LISPM
you might find it possible to change some type bits in the stack words
to make the arguments PUSHed onto the stack into a CDR-coded list.
While we are discussing such low-level issues, it is worth thinking about
how difficult it is to take advantage of the possibility of sharing
&Rest lists. Basically there are two ways to do it. If you are willing to
give up or tremendously complicate separate compilation you can compile
a function CALL using special knowledge of the definition of the Callee.
For example, a call using APPLY could jump into the middle of the
function entry sequence, after the point where &Rest lists normally
get created. This would be a major break with Lisp tradition. Alternatively,
you must use several different calling conventions and pass along
enough information so that the Callee knows how its arguments have been
encoded. This will slow down every function call by the amount needed
to encode/decode this information, and complicate the implementation
considerably. Which option do you prefer?
Well, I know that I use APPLY a whole lot. Not as often as LIST and
CAR, certainly, but more often than I would have expected.
I don't use APPLY very much. I am sure that neither of us are
biased because of our programming styles, right?
APPENDIX
The rest of this message is an edited dribble file, showing how NIL
compiles function calls using &Rest arguments. My comments are
shown /* C Style */ to distinguish them from comments inserted by
the disassembler. I deleted several screenfuls to shorten the message,
so this does not fully illustrate how much hidden complexity there is
in a function call.
(:OPENED "VAX5::OFFICE$DISK:[ELIOT]FOO.TXT;2")
(defun foo (&rest x)
(setf (cadr x) 'bang))
(defun bar (z)
(apply #'foo z))
(defun baz (a b c)
(foo a b c))
;[Compiled foo bar and baz.]
(defvar z '(1 2 3))
Z
(bar z)
BANG
z
(1 2 3) ;Didn't get side effected.
(disassemble 'foo)
0: WORD 1024 ;Save register(s) FLP
2: MOVAL l↑-420,FLP
9: MINICALL CL$MS_HNDL_RS,(COMPILER:REQ 0)
13: MINICALL CL$MS_ANDREST_LIST,-8(FP)
17: MOVL AR1,b↑-8(FP)
21: MOVL b↑-8(FP),AR1
25: MINICALL CL$MS_CDR
28: PUSHL AR1
30: MOVL b↑4(FLP),AR1 ;'BANG
34: MINICALL CL$MS_SET_CAR
37: RET
(disassemble 'bar)
... /* 15 lines deleted */
41: PUSHL b↑-4(FLP) ;#'FOO
50: MINICALL CL$MS_STACKIFY /* The arguments get spread out here */
54: CALLS R0,@b↑8(SP)
58: RET
(disassemble 'baz)
/* 13 lines deleted */
33: PUSHL b↑24(AP)
36: PUSHL b↑20(AP)
39: PUSHL b↑16(AP)
50: PUSHL b↑-4(FLP) ;#'FOO
55: CALLS s↑#6,@b↑8(SP)
59: RET
==============
Vaxlisp is similar. BAZ essentially compiles into a jump to FOO. BAR
remains complex.
==============
∂30-Mar-88 1055 Common-Lisp-mailer &Rest Lists
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 30 Mar 88 10:52:48 PST
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 30 Mar 88 11:00-EST
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 85770; 30 Mar 88 09:07:29-EST
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 97731; Wed 30-Mar-88 08:50:23-EST
Date: Wed, 30 Mar 88 08:52 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com after 1-April-88)
COMMENTS: NOTE %acorn@oak... CHANGES TO @GOLD-HILL.COM ON 1-April-88
To: ELIOT@cs.umass.edu
Subject: &Rest Lists
Cc: common-lisp@SAIL.STANFORD.EDU
Calls made using APPLY are not specially optimized. However, FOO can
be compiled using full knowledge of the body of FOO. So if FOO does
not return its &Rest list it can be CONSed on the stack.
This "analysis" stuff is not really valuable. Without global program
knowledge, the vast majority of these cases will be undecidable. If
you pass any cons of the rest arg to any function, and return the
value of any other function, then you can't decide it because the two
functions could communicate via shared state: e.g.,
--> file 1:
(let ((shared-state nil))
(defun bar (x)
(setq shared-state x))
(defun foo ()
shared-state))
--> file 2:
(defun test (&rest arg)
(bar arg)
(foo))
Clearly, TEST returns its rest arg, and the only way for the compiler
to know this is to have global knowledge of the functions FOO and BAR
The only way around this is to re-write test:
(defun test (&rest arg1)
(let ((arg (copy-list arg1)))
(bar arg)
(foo)))
Which is exactly what you have to do to eliminate sharing when the
default is to allow sharing. (Note that in this case, the compiler
could infer that arg1 could be a "stack-list" :-)
My point: relying on the compiler to "infer" stuff that should be
directly expressable is a bad idea. It should be clear that if
the default is to share rest-arg conses passed by apply, one
can get the desired behavior possibly at the cost of having to
call copy-list. If the default is to copy, then in most cases,
the compiler will not be able to eliminate the copying and there
will be run-time cost.
While we are discussing such low-level issues, it is worth thinking about
how difficult it is to take advantage of the possibility of sharing
&Rest lists. Basically there are two ways to do it. If you are willing to
give up or tremendously complicate separate compilation you can compile
a function CALL using special knowledge of the definition of the Callee.
For example, a call using APPLY could jump into the middle of the
function entry sequence, after the point where &Rest lists normally
get created. This would be a major break with lisp tradition.
you must use several different calling conventions and pass along
enough information so that the Callee knows how its arguments have been
encoded. This will slow down every function call by the amount needed
to encode/decode this information, and complicate the implementation
considerably. Which option do you prefer?
Having mulitple function entry points to support different calling
conventions sounds like a good strategy to exploit compile-time
knowledge of the structure of the called function. A classic example
of this is for type-checking. If checked and unchecked entries are
available, then the compiler can set up an unchecked call if the
types are known to be correct. There need be no run-time set-up or
overhead.
...mike beckerle
Gold Hill
∂30-Mar-88 1140 Common-Lisp-mailer &Rest Lists
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 30 Mar 88 11:40:19 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 30 Mar 88 07:14:53 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 30 Mar 88 07:14:46 EST
Date: Wed, 30 Mar 88 07:16 EST
From: Barry Margolin <barmar@Think.COM>
Subject: &Rest Lists
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8803300741.AA28407@Think.COM>
Message-Id: <19880330121607.8.BARMAR@OCCAM.THINK.COM>
Date: Tue, 29 Mar 88 12:12 EDT
From: ELIOT@cs.umass.edu
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
Date: Thu, 24 Mar 88 17:12 EDT
From: ELIOT@cs.umass.edu
From: Barry Margolin <barmar@think.COM>
To: ELIOT@cs.umass.EDU
What I mean by saying that "Using APPLY is probably inefficient
anyhow" is that you will incur the overhead of a full extra function
call that probably cannot be optimized away. ...
What extra function call? I would hope that the compiler will inline
code calls to APPLY. (apply #'foo '(1 2 3)) should generate code at
least as good as (foo 1 2 3), and the only difference between (apply
#'foo '(1 2 3)) and (apply foo '(1 2 3)) should be whether it extracts
the function from FOO's function or value cell. In the implementation
I use (a Lispm), APPLY is a single instruction.
Is it an instruction, or a microcoded subroutine? :-)
I don't have access to the microcode source, so I can't tell. All I
know is that it is one macroinstruction. It is probably a microcode
routine, because it still has to do a significant amount of work, such
as checking the number of arguments supplied against the allowed number
of arguments for the function.
The only extra
inefficiency that APPLY might incur is the one YOU are advocating --
copying its last argument -- which makes your reasoning circular.
I looked at both VAXLISP and NIL to see what they do. Both of these
implementations spread the arguments out on the stack in the calling
function and collect them back into a list when entering the function
with the &Rest argument. Consequently they might use stack lists,
but they cannot share list stucture as you are proposing.
Because these implementors chose not to share the apply argument and the
&rest argument, they must do the spread and collect. This extra
function call you mentioned is directly caused by the non-sharing. You
implied that there was some inefficiency already inherent in APPLY, so
that adding the spread/collect wouldn't make it much slower.
A normal function call [i.e. (foo 1 2 3)] gets compiled as a series
of individual PUSHES as the arguments are evaluated. (Equivalently,
memory for the entire set of arguments can be allocated on the stack
and individual values MOVEd into the correct location.)
A function call using APPLY would PUSH the initial arguments and then
call a hand-coded assembly routine to push the rest of the arguments.
Consequently, the state of the stack when FOO is entered is the same
regardless of how FOO gets called, so FOO cannot differentiate
calls moderated by APPLY from normal function calls. Your APPLY
microprogram might do something similar, and it certainly could.
Calls made using APPLY are not specially optimized. However, FOO can
be compiled using full knowledge of the body of FOO. So if FOO does
not return its &Rest list it can be CONSed on the stack. On a LISPM
you might find it possible to change some type bits in the stack words
to make the arguments PUSHed onto the stack into a CDR-coded list.
What I believe the Lispm APPLY does is to push each of the regular
arguments onto the stack, then push the list argument onto the stack,
and set a bit indicating that the last argument should be spread if
necessary. When entering the callee, if there are fewer regular lambda
variables than regular arguments, the extra regular arguments are turned
into a stack-consed list whose tail is the list argument (as you
described in your last sentence above), and the &rest argument is bound
to this. If there are more regular lambda variables than regular
arguments, then values are popped from the list argument and stored in
the appropriate stack locations for those lambda variables, and the
&rest arg is bound to what is left of the list argument.
Except for the use of stack lists for regular arguments that become part
of an &rest variable, no special support is necessary for the above.
And the use of stack lists is independent of the other features.
Stack-consed &rest arguments merely guarantee that they NEVER cons.
While we are discussing such low-level issues, it is worth thinking about
how difficult it is to take advantage of the possibility of sharing
&Rest lists. Basically there are two ways to do it. If you are willing to
give up or tremendously complicate separate compilation you can compile
a function CALL using special knowledge of the definition of the Callee.
For example, a call using APPLY could jump into the middle of the
function entry sequence, after the point where &Rest lists normally
get created. This would be a major break with Lisp tradition. Alternatively,
you must use several different calling conventions and pass along
enough information so that the Callee knows how its arguments have been
encoded. This will slow down every function call by the amount needed
to encode/decode this information, and complicate the implementation
considerably. Which option do you prefer?
Well, I guess what the Lispm does is the latter (actually, there is also
some of the former -- optional arguments are implemented by having each
of the first N instructions do the defaulting for the corresponding
argument, and the first M are skipped when M optional arguments have
been supplied). But I don't think the overhead need be as much as you
think. I suspect that it could be implemented such that its worst case
behavior is the same expense as NIL's regular case.
Here's how I would describe a good argument processing algorithm (I'm using Lisp for
convenience, this code doesn't come from the Lispm, or any existing implementation):
(defun process-arguments (function arg-array spread-last-arg-p)
;; ARG-ARRAY is the portion of the activation record containing the arguments,
;; which were pushed by the caller.
(multiple-value-bind (n-bound-vars spread-last-var-p) ; n-bound-vars doesn't
; include &rest var
(function-arg-info function) ;; ignore optional/key for now
(let ((n-ordinary-args (if spread-last-arg-p
(1- (length arg-array))
(length arg-array))))
;; Check for optimal case first
(unless (and (= n-bound-vars n-ordinary-args)
(eq spread-last-arg-p spread-last-var-p))
(let ((spread-arg (if spread-last-arg-p
(aref arg-array n-ordinary-args)
nil)))
(cond ((< n-bound-vars n-ordinary-args)
(do ((i (1- n-ordinary-args) (1- i)))
((= i n-bound-vars))
(push (aref arg-array i) spread-arg)))
((> n-bound-vars n-ordinary-args)
(do ((i n-bound-vars (1+ i)))
((= i n-ordinary-args))
(if (null spread-arg) (error "Not enough arguments supplied")
(push-argument (pop spread-arg))))))
(if (and spread-arg spread-last-var-p)
(push-argument spread-arg)
(error "Too many arguments supplied")))))))
The above example doesn't try to do stack-consing. Therefore its
worst-case performance is in the case of (apply #'(lambda (&rest arg)
...) <n individual args> NIL), consing n elements, just like NIL. But
in the case where the &rest arg exactly matches the last argument to
APPLY, neither loop executes. (apply #'(lambda (<n individual args>)
...) <list>) also does O(n) work, but it doesn't cons, so it is cheaper
than the first example. In general, my algorithm is O(n-ord-args -
n-ord-vars), whereas NIL is O(length(last-apply-arg)).
Well, I know that I use APPLY a whole lot. Not as often as LIST and
CAR, certainly, but more often than I would have expected.
I don't use APPLY very much. I am sure that neither of us are
biased because of our programming styles, right?
Actually, I suspect it has to do with the applications more than style.
APPLY is used frequently when writing intermediary routines dealing with
things like files, because you are passed an options list suitable for
OPEN, and you must use APPLY to invoke OPEN. Much of what I do requires
this.
One nice thing about the modularity of the NIL generated code: it could
easily be converted to an implementation like this without changing the
code generator. Something equivalent to the above could be implemented
in CL$MS_STACKIFY (it would do almost nothing), CL$MS_HNDL_RS (this
would contain the two loops), and CL$MS_ANDREST_LIST (this would
correspond to my last IF form). In fact, how do I know from only
looking at the code you supplied that it DOESN'T do that? (The answer
is that I assume you have looked at the implementation, and it does what
you say).
barmar
∂01-Apr-88 2328 Common-Lisp-mailer &Rest Lists
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 1 Apr 88 23:27:52 PST
Received: from relay2.cs.net by RELAY.CS.NET id ab03466; 2 Apr 88 2:23 EST
Received: from cs.umass.edu by RELAY.CS.NET id cd10549; 2 Apr 88 2:14 EST
Date: Fri, 1 Apr 88 15:15 EDT
From: ELIOT@cs.umass.edu
Subject: &Rest Lists
To: Common-Lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"Common-Lisp@sail.stanford.edu"
In order to clarify the importance of optimized handling of &Rest
arguments, compared to the importance of specifying their semantics more
precisely I have collected some statistics. The functions used to
collect these are included at the end of this message. I encourage
others to use these functions to obtain measurements of their own
code.
Using APROPOS it is possible to measure how many functions take &Rest
arguments. On an Explorer I got the following results:
PACKAGE with &Rest Without Percent
------------------------------------
LISP 70 580 10.7
SI 73 3384 2.1
ZWEI 66 2324 2.7
TV 79 1177 6.2
FS 54 707 7.0
FORMAT 11 105 9.4
------------------------------------
Subtotal 283 7697 3.5
KEE 234 5120 4.3 (IntelliCorp's package)
------------------------------------
Total 517 12817 3.8
Unfortunately, since calls to APPLY are optimized they cannot be
analyzed with WHO-CALLS. Instead I searched the source code of the NIL
compiler for lines containing the strings "(APPLY" and "&REST". These
include comment lines, and parsing of argument lists. (The paren in
"(APPLY" eliminates some of that.)
From nil$disk:[nil.h]*.lsp
Lines Textually Containing:
"(APPLY" "&Rest" "defun" TOTAL LINES
-------------------------------------------------
18 61 859 24799
So 7.1% of these function definitions take &rest arguments. (Including
NIL specific &Restv, &Restl.)
Too many assumptions must be made for a realistic estimate of
the actual optimization value of specially handling &rest
lists to be made using these numbers. These numbers all
refer to source code statistics, while the actual optimization
depends upon instruction stream characteristics. However,
the fact that &Rest is used in a small minority of function
definitions, while APPLY is very rare strongly suggests that
their combined use in a single function call is very rare
indeed. Consequently these statistics do not support the idea
that this case needs to be highly optimized.
The 70 Explorer LISP package (i.e. Common Lisp) functions with &Rest
arguments are:
------------------------------------------------------
;;; Unclassified:
MAPHASH MAKE-CONCATENATED-STREAM ARRAY-ROW-MAJOR-INDEX
MAKE-BROADCAST-STREAM ADJUST-ARRAY ROOM
;;; IO Functions:
YES-OR-NO-P CERROR ERROR FORMAT WARN BREAK Y-OR-N-P
;;; Primitives perhaps known to the compiler:
APPEND MAPC = MAX NOTANY SBIT BIT < MAPCON /= MAPLIST LIST* MAPCAN AREF
ARRAY-IN-BOUNDS-P / CONCATENATE MAPCAR MAPL - VECTOR FUNCALL MIN XOR
EVERY NOTEVERY <= APPLY + MAP VALUES * >= SOME LIST NCONC IGNORE >
LOGIOR LOGEQV LOGXOR LOGAND LCM GCD BOOLE
CHAR-NOT-GREATERP CHAR-NOT-LESSP CHAR-NOT-EQUAL CHAR> CHAR< CHAR/=
CHAR-EQUAL CHAR= CHAR<= CHAR-LESSP CHAR-GREATERP CHAR>=
------------------------------------------------------
The overall importance of optimizing CONSing also depends upon the speed
of CONSing. Since one of the most important known uses of APPLY where
&Rest arguments are an issue involves calling FORMAT it is important to
compare CONSing speed with I/O speed. On an Explorer II, GC-ON,
everything compiled:
Function Calls Time Normalized to 1,000,000 Calls
-------------------------------------------------------------------
(foo (cons 1 2)) 10,000,000 140.8 14.8
NIL 1,000,000 1.3 1.3
(foo 2) 1,000,000 4.53 4.53
(write-char #\a) 10,000 3.74 374.0
(probe-file ...) 100 43.7 437,000
[using a string as a pathname, non-local file,
connection already established.]
FOO is a null function needed to prevent optimization.
(dotimes (i 10000000) (cons 1 2)) is optimized to:
(dotimes (i 10000000) nil) so:
(dotimes (i 10000000) (foo (cons 1 2))) must be used
instead. FOO is defined with:
(defun foo (x) x)
On the basis of this I conclude that the common idiom
(apply #'format ...) does not deserve special attention
to the number of CONSes performed in creating the &Rest list
for FORMAT.
=================================================================
The actual functions used to collect some of this data follow.
;;; -*- Mode:Common-Lisp; Package:USER; Base:10 -*-
(defvar *count* 0)
(defvar *not-count* 0)
(defvar *fns* nil)
(defun rest-p (x)
(cond ((and (not (macro-function x))
(not (special-form-p x))
(member '&rest (arglist x)))
(push x *fns*)
(incf *count*) t)
(t (incf *not-count*)
nil)))
(defun test (pkg)
(setq *count* 0)
(setq *not-count* 0)
(setq *fns* nil)
(apropos "" :package pkg :inherited nil :predicate #'rest-p :fboundp t :inheritors nil)
(format t "~&There are ~a functions with &Rest arguments, ~a without in package ~a"
*count* *not-count* pkg))
(defun file-search (file str)
(let ((count 0)
(lines 0))
(with-open-file (stream file)
(loop for line = (read-line stream nil nil)
while line
do (incf lines)
(when (search str line :test #'char-equal)
(format t "~&~a" line)
(incf count))))
(values count lines)))
(defun file-search-list (files str)
(let ((count 0)
(lines 0))
(dolist (file files)
(multiple-value-bind (a b) (file-search file str)
(setq count (+ count a))
(setq lines (+ lines b))
(format t "~&File ~a Count ~a; lines ~a Total count ~a, lines ~a" file a b count lines)))
(format t "~&Grand Total count ~a; lines ~a" count lines)
(values count lines)))
;;; (file-search-list (pathname "nil$disk:[nil.h]*.lsp") "(APPLY")
∂02-Apr-88 0959 Common-Lisp-mailer Re: &Rest Lists
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 2 Apr 88 09:58:26 PST
Received: from aiva.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa01191; 2 Apr 88 18:55 BST
From: Jeff Dalton <jeff%aiva.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Sat, 2 Apr 88 18:54:38 bst
Message-Id: <29307.8804021754@aiva.ed.ac.uk>
To: Common-Lisp@sail.stanford.edu, ELIOT <@relay.cs.net:ELIOT@cs.umass.edu>
Subject: Re: &Rest Lists
> Date: Fri, 1 Apr 88 15:15 EDT
> From: ELIOT@edu.umass.cs
> the fact that &Rest is used in a small minority of function
> definitions, while APPLY is very rare strongly suggests that
> their combined use in a single function call is very rare
> indeed. Consequently these statistics do not support the idea
> that this case needs to be highly optimized.
While it is true that the statistics do not support the optimization,
there are clearly additional factors to consider (as you have
mentioned). One is that programmers may avoid this case because they
know it will often be inefficient. Another is that, in a dynamic
analysis, the cases where the construction is used may turn out to be
important. I know that I use it less often than I would like to.
> FOO is a null function needed to prevent optimization.
> (dotimes (i 10000000) (cons 1 2)) is optimized to:
> (dotimes (i 10000000) nil) so:
Why isn't it optimized to just NIL?
∂04-Apr-88 0649 Common-Lisp-mailer RE: &Rest Lists
Received: from HAL.CAD.MCC.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 06:49:01 PDT
Received: from CHANGABANG.CAD.MCC.COM by HAL.CAD.MCC.COM via CHAOS with CHAOS-MAIL id 77805; Mon 4-Apr-88 08:21:10 CDT
Date: Mon, 4 Apr 88 08:20 CDT
From: William D. Gooch <gooch@CHANGABANG.CAD.MCC.COM>
Subject: RE: &Rest Lists
To: ELIOT%cs.umass.edu@MCC.COM
cc: Common-Lisp@SAIL.STANFORD.EDU
In-Reply-To: <8804020802.AA15477@cadillac>
Message-ID: <880404082053.2.GOOCH@CHANGABANG.CAD.MCC.COM>
Reply-To: gooch@MCC.COM
Postal-address: MCC-CAD 3.8108
Business-phone: (512) 338-3661
Instead of beating &rest into dust because it isn't exactly the thing
you want, why not talk adding about a different mechanism that is?
Perhaps you would like something that supports an indefinite number
of arguments but does not make them accessible as a list.
-- William D. Gooch
∂04-Apr-88 0724 Common-Lisp-mailer &rest replacement/addition
Received: from SPICE.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 4 Apr 88 07:24:49 PDT
Received: from SPICE.CS.CMU.EDU by SPICE.CS.CMU.EDU; 4 Apr 88 10:24:40 EDT
To: common-lisp@sail.stanford.edu
cc: spe@SPICE.CS.CMU.EDU
Subject: &rest replacement/addition
Date: Mon, 04 Apr 88 10:24:30 EDT
From: Sean.Engelson@SPICE.CS.CMU.EDU
In view of all of the recent furor about &rest, perhaps, as Mr. Gooch
suggests, a different mechanism is in order. I'd like to suggest one,
as a starting point for discussion. This idea may have been discussed
already, or maybe even implemented somewhere, but I'll suggest it
anyway. We need a way to have indefinite numbers of arguments, without
the overhead and semantic problems inherent in consing up (or not
consing up) lists. How about a new lambda-list keyword, maybe
&more-args, and a couple of special forms to deal with them, DO-ARGS
and NEXT-ARG, maybe ARGS-TO-LIST even. So you'd have code like the following:
(defun fu (a &more-args)
(do-args (arg)
...code...
(moby-calculation a arg)
...more code...
))
etc...
The nice thing about this is that the implementation can do whatever it
wants with things, shove them on the stack, save APPLY lists, etc., and
the semantics remain clean. The disadvantage is that this introduces
more 'side-effecting' semantics into the language, but then, Common
Lisp was never too clean on that score anyway.
What do you all think?
-Sean Engelson-
Carnegie-Mellon University
∂04-Apr-88 0810 Common-Lisp-mailer &rest replacement/addition
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 08:10:03 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 4 Apr 88 11:08:12 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 4 Apr 88 11:08:08 EDT
Date: Mon, 4 Apr 88 11:09 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: &rest replacement/addition
To: Sean.Engelson@spice.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu, spe@spice.cs.cmu.edu
In-Reply-To: <8804041424.AA20946@Think.COM>
Message-Id: <19880404150918.4.BARMAR@OCCAM.THINK.COM>
Date: Mon, 04 Apr 88 10:24:30 EDT
From: Sean.Engelson@spice.cs.cmu.edu
(defun fu (a &more-args)
(do-args (arg)
...code...
(moby-calculation a arg)
...more code...
))
This is similar in spirit to MacLisp's lexprs, which also had special
forms for accessing the arguments. However, it needs a minor fix to
prevent it from sharing one of their faults, too. &MORE-ARGS should be
followed by a symbol, which would be used as an argument to the special
forms. This way you can have nested functions that use &MORE-ARGS and
be able to access the outer function's arguments from the inner
function.
Actually, if this were added, the operations that extract the arguments
need not be special forms. &MORE-ARGS <var> could bind <var> to an
object of type MORE-ARGS. Common Lisp would only specify accessors for
this object, so it could be passed along with no possibility of strange
side-effects. APPLY could also be extended to allow a MORE-ARGS in
place of a list as its last argument.
barmar
∂04-Apr-88 0932 Common-Lisp-mailer Re: &rest replacement/addition
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 09:31:56 PDT
Return-Path: <rst@Think.COM>
Received: from pozzo.think.com by Think.COM; Mon, 4 Apr 88 12:29:54 EDT
Received: by pozzo.think.com; Mon, 4 Apr 88 12:29:50 edt
Date: Mon, 4 Apr 88 12:29:50 edt
From: rst@Think.COM
Message-Id: <8804041629.AA00637@pozzo.think.com>
To: Sean.Engelson@spice.cs.cmu.edu, barmar@Think.COM
Subject: Re: &rest replacement/addition
Cc: common-lisp@sail.stanford.edu, spe@spice.cs.cmu.edu
From: Barry Margolin <barmar@Think.COM>
Subject: &rest replacement/addition
Actually, if this were added, the operations that extract the arguments
need not be special forms. &MORE-ARGS <var> could bind <var> to an
object of type MORE-ARGS. Common Lisp would only specify accessors for
this object, so it could be passed along with no possibility of strange
side-effects. APPLY could also be extended to allow a MORE-ARGS in
place of a list as its last argument.
barmar
But can an object of type MORE-ARGS be returned from a function, or
otherwise stuffed in data structures which survive the dynamic extent
of the function call that spawned them? That's what this whole
argument started with...
(Sean's original proposal had no &more-args variables. Any
implementation would, of necessity, have some such thing internally,
but users would not be able to get their hands on them).
rst
∂04-Apr-88 1002 Common-Lisp-mailer Re: &rest replacement/addition
Received: from rdcf.sm.unisys.com by SAIL.Stanford.EDU with TCP; 4 Apr 88 10:01:40 PDT
Received: by rdcf.sm.unisys.com (sdcrdcf) (5.51/Domain/jpb/2.9)
id AA19097; Mon, 4 Apr 88 09:01:17 PST
Message-Id: <8804041701.AA19097@rdcf.sm.unisys.com>
Received: from XERXES by sdcrdcf with PUP; Mon, 4 Apr 88 09:00 PST
From: darrelj@sm.unisys.com
Date: 4 Apr 88 10:00 PDT (Monday)
Subject: Re: &rest replacement/addition
In-Reply-To: Barry Margolin <barmar@Think.COM>'s message of Mon, 4 Apr 88 11:09 EDT
To: Barry Margolin <barmar@think.com>
Cc: Sean.Engelson@spice.cs.cmu.edu, common-lisp@sail.stanford.edu,
spe@spice.cs.cmu.edu
Date: Mon, 4 Apr 88 11:09 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: &rest replacement/addition
To: Sean.Engelson@spice.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu, spe@spice.cs.cmu.edu
Date: Mon, 04 Apr 88 10:24:30 EDT
From: Sean.Engelson@spice.cs.cmu.edu
(defun fu (a &more-args)
(do-args (arg)
...code...
(moby-calculation a arg)
...more code...
))
This is similar in spirit to MacLisp's lexprs, which also had special
forms for accessing the arguments. However, it needs a minor fix to
prevent it from sharing one of their faults, too. &MORE-ARGS should be
followed by a symbol, which would be used as an argument to the special
forms....
barmar
Or like the Interlisp nospread, in which
(LAMBDA N (COND ((> N 3) (F (ARG N 1) ...)...)
has the same result as Common Lisp
(LAMBDA (&REST N) (COND((> (LENGTH N)3) (F (NTH N 1) ...)....)
The lambda variable is bound to the count, the actual arguments
usually hide in the stack, but that is of course an implementation
decision. (ARG var pos) fetches the specified positional argument for
the named nospread variable. The compiler often produces better code
when the named variable is the local argument (in Interlisp-D (ARG N
1) emits identical code for a local nospread argument as for the first
argument of a regular lambda arglist).
There is even a (SETARG var pos) for modifying one of the arguments.
It of course has most of the same implementation problems that started
the &REST and APPLY discussion if you decide to implement it via
lists. However, since there is no name for all arguments, you don't
give APPLY the same oportunity to copy or not copy the list which
might be coming in.
Darrel J. Van Buer
p.s. Most interlisp functions which use nospread arguments are of two kinds:
Ones like append which might otherwise be coded as commonlisp &REST
where compiler macros would normally get rid of the arglist consing anyway.
Ones implementing a Commonlisp &OPTIONAL argument.
∂04-Apr-88 1041 Common-Lisp-mailer Re: &rest replacement/addition
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 4 Apr 88 10:37:49 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 4 Apr 88 13:35:29 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 4 Apr 88 13:35:24 EDT
Date: Mon, 4 Apr 88 13:36 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: &rest replacement/addition
To: rst@Think.COM
Cc: Sean.Engelson@spice.cs.cmu.edu, common-lisp@sail.stanford.edu,
spe@spice.cs.cmu.edu
In-Reply-To: <8804041629.AA00637@pozzo.think.com>
Message-Id: <19880404173633.6.BARMAR@OCCAM.THINK.COM>
Date: Mon, 4 Apr 88 12:29:50 edt
From: rst@Think.COM
From: Barry Margolin <barmar@Think.COM>
Subject: &rest replacement/addition
Actually, if this were added, the operations that extract the arguments
need not be special forms. &MORE-ARGS <var> could bind <var> to an
object of type MORE-ARGS. Common Lisp would only specify accessors for
this object, so it could be passed along with no possibility of strange
side-effects. APPLY could also be extended to allow a MORE-ARGS in
place of a list as its last argument.
barmar
But can an object of type MORE-ARGS be returned from a function, or
otherwise stuffed in data structures which survive the dynamic extent
of the function call that spawned them? That's what this whole
argument started with...
No, I don't think that's what started this particular argument. The
issue of stack-consed &REST lists is completely independent of the issue
of side-effects on shared &REST lists. They are two orthogonal
mechanisms for speeding up calls to &REST functions; in fact, they each
address different cases (stack consing speeds up normal calls, sharing
speeds up calls via APPLY). The above only addresses the issue of
preventing the strange side-effects that the latter allows, which is
what this discussion has been about. I almost added a sentence that
said that this doesn't affect the stack-allocation issue, as those
implementations that currently allocate &REST lists on the stack would
probably want to allocate &MORE-ARGS objects there, too.
Dynamic-extent &REST lists have never been valid Common Lisp (there are
examples on p.64 of CLtL that fail when &REST lists are stack-consed).
If this new proposal were to be adopted, I doubt X3J13 would allow them
to be stack-allocated, either. Presumably, Symbolics's excuse for
continuing to stack-cons &REST lists is that they were doing so before
Common Lisp, and they haven't gotten around to changing it. They
wouldn't have such an excuse with the new mechanism.
barmar
∂05-Apr-88 0550 Common-Lisp-mailer Re: &rest replacement/addition
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 5 Apr 88 05:50:16 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 5 Apr 88 08:49-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86182; 5 Apr 88 08:47:36-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98040; Tue 5-Apr-88 07:52:45-EST
Date: Tue, 5 Apr 88 06:53 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: rst@Think.COM
Subject: Re: &rest replacement/addition
Cc: Sean.Engelson@spice.cs.cmu.edu, barmar@Think.COM,
common-lisp@sail.stanford.edu, spe@spice.cs.cmu.edu
But can an object of type MORE-ARGS be returned from a function, or
otherwise stuffed in data structures which survive the dynamic extent
of the function call that spawned them? That's what this whole
argument started with...
I agree. Are there any examples of CL constructs which allow a
reference to an object which has only dynamic extent? The closest
thing I can think of is WITH-OPEN-FILE, but that just insures that
the stream is closed, not that it's storage is reclaimed. My
intuition is also that allowing a first-class reference for a
dynamic-extent object is a bad idea.
...mikeb
∂05-Apr-88 1437 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 5 Apr 88 14:37:35 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Tue, 5 Apr 88 11:29:13 PDT
Date: Tue, 5 Apr 88 11:29:13 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <880405112913.2020021c@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: Defstructs
Date: Tue, 5-APR-1988 10:55 MST
X-VMS-Mail-To: @COMMON-LISP
I'm trying to create structures on the fly. I have a problem with:
(defun test (&aux x)
(defstruct foo a b c)
(setf x (make-foo))
(setf (foo-a x) 1)
)
When TEST is interpreted, all is fine. When it is compiled the
function (foo-a) is undefined since it isn't created by defstruct
until run time. In my actual code FOO is a symbol that's build based
upon some args to TEST, therefore I can't simply put the defstruct at
the top level. Any ideas??
Steve Pothier
SAIC
<pothiers%tuva.sainet@nmfecc.arpa>
∂05-Apr-88 2257 Common-Lisp-mailer &Rest args and Optimizations
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 5 Apr 88 22:57:35 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ah00702; 6 Apr 88 2:02 EDT
Received: from cs.umass.edu by RELAY.CS.NET id cd11113; 6 Apr 88 1:50 EDT
Date: Tue, 5 Apr 88 15:38 EDT
From: MURRAY@cs.umass.edu
Subject: &Rest args and Optimizations
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: CLMAIL
NOTE: The ELIOT that has been arguing about &Rest args
is Chris Eliot, and NOT Eliot Moss, as someone believed.
Sharing an &Rest list with a list given to apply is clearly an optimization,
and as such, should not be required. However, if it is allowed,
destructively modifying an &rest list becomes extremely dangerous, and hence
should never be done. In fact, it might be appropriate to say it is "an error"
to modify one.
I think this is a big mistake. The cleaner approach to this and other
issues like it is to consider the language issues first. A well-defined
language that is portable, easy to understand and debug is what's
important. Optimizations are the domain of the implementation.
That's the whole idea behind DECLARE.
Smart Compilers, tricky type representations, multiple function entry points,
etc, are important, but are all PERFORMANCE issues, not semantic ones.
In the case of &Rest args, it seems to me that the right way to deal
with it is to say the list is always freshly consed. If a compiler
can recognize that the list is never modified, it would be free
share it's structure with an Apply arg. If it can determine the
list is inaccessable on function return, it is free to stack-allocate it.
Providing declarations to help the compiler are very useful, but still can
be ignored without changing the program's correctness.
In regards to &More, or whatever, I think the &Rest mechanism is
perfectly adequate. A stack consed &Rest eliminates the conses,
which seems to be what people want to avoid.
∂05-Apr-88 2305 Common-Lisp-mailer &rest replacement/addition
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 5 Apr 88 23:05:25 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab00602; 6 Apr 88 1:54 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bk11113; 6 Apr 88 1:43 EDT
Date: Tue, 5 Apr 88 12:55 EDT
From: ELIOT@cs.umass.edu
Subject: &rest replacement/addition
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
I had hoped that the semantics of &rest lists could be completely
specified without or before getting into murky side issues like
this.
Given my position on previous issues it should not be a surprise that
I am strongly opposed to all of the &rest replacement/additon
proposals. I consider &rest to be a fine feature that is completely
adequate for solving the problems of passing indefinate numbers of
arguments. I consider it sufficiently good that it is worth spending
considerable effort giving it a precise specification, as we have
been trying to do. I don't think it needs replacement.
There has only been one criticism of &Rest lists. There is the
impression that this feature introduces an unacceptible inefficiency
in programs. This impression is sufficiently strong that people are
considering pulling one of Maclisp's kludgest features out of its
grave, introducing new strange data types to Common Lisp and doing
all kinds of horrible things in order to eliminate this ineficiency.
From the data that is available it seems that this is just
being scared of the dark. The statistics I collected do not
directly measure the bottom line efficiency of using &Rest lists.
This certainly means that it is "possible" for dynamic situations to
exist where the efficiency of &Rest lists is exagerated. It is also
possible that my data sample is somehow unrepresentative.
Someone suggested that the low usage of &Rest could be explained because
programmers fear its inefficiency. This is unlikely. The code I
analyzed was Lisp Machine system code. Most of this code was written
as ZetaLisp code, in which &Rest lists are *more* efficient than they
are in Common Lisp. (Because of stack consing.) In fact, while &Rest
may be less efficient in Common Lisp it may be used more, perhaps
because it is better specified and thus more valuable from an algorithmic
standpoint.
About 10% of the Common Lisp functions used &Rest arguments. I believe
this is probably an upper bound. A great deal of effort has been spent
on this mailing list thinking of ways to generalize all of the primitives
in Common Lisp. Despite this effort to generalize the primitives, 90%
of the time there has been no good reason to use &Rest lists.
Furthermore, I believe there is an explanation for why people "have
the impression" that &rest/Apply must be highly optimized. Both of these
are used in somewhat unusual coding situations that require somewhat
more thought than normal. A tricky piece of code requires more attention
from the programmer. A common trap is to think the program spends as much
time executing code as the programmer spends writing it.
Without any data to support another position all of the proposals to
replace &Rest or augment it should be rejected, and its semantics should
be precisely defined as I have previously proposed.
∂06-Apr-88 0926 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:26:16 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Wed, 6 Apr 88 09:23:25 PDT
Date: Wed, 6 Apr 88 09:23:25 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <880406092325.20a0021c@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: CLOS
Date: Wed, 6-APR-1988 08:50 MST
X-VMS-Mail-To: @[.SIGS]COMMON-LISP
Anyone know where I can get CLOS?
Steve Pothier
<pothiers%tuva.sainet@nmfecc.arpa>
∂06-Apr-88 0956 Common-Lisp-mailer &rest replacement/addition
Received: from WAIKATO.S4CC.Symbolics.COM ([128.81.51.90]) by SAIL.Stanford.EDU with TCP; 6 Apr 88 09:56:26 PDT
Received: from JEWEL-CAVE.S4CC.Symbolics.COM by WAIKATO.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 167878; Wed 6-Apr-88 12:43:05 EDT
Date: Wed, 6 Apr 88 12:43 EDT
From: Stephen Robbins <Stever@WAIKATO.S4CC.Symbolics.COM>
Subject: &rest replacement/addition
To: ELIOT@cs.umass.edu
cc: common-lisp@sail.stanford.edu
In-Reply-To: Msg of 5 Apr 1988 12:55-EDT from ELIOT at cs.umass.edu
Message-ID: <19880406164304.2.STEVER@JEWEL-CAVE.S4CC.Symbolics.COM>
Date: Tuesday, 5 April 1988 12:55-EDT
From: ELIOT at cs.umass.edu
There is the impression that this feature introduces an
unacceptible inefficiency in programs.
From the data that is available it seems that this is just being
scared of the dark. It is also possible that my data sample is
somehow unrepresentative.
The code I analyzed was Lisp Machine system code.
Last year, I wrote a window system in Common Lisp. I needed a simple
flavors system to support it. My generic function dispatcher used
&REST and APPLY to pass arguments from the generic function to the
method handling the generic function.
Since the window system was used everywhere in our product, we needed
maximum efficiency in time and space. We found that &REST CONSing was
taking time and space we couldn't afford (the things it was doing to
the freelist! :-) So much so that we had to make it a general shop
policy not to use &REST.
Maybe this is an issue of "the compiler writers should be smarter."
But we're a startup. We can't wait for the compiler writers to get
smarter. For that matter, we can't wait for an &REST replacement.
If Common Lisp wants to be commercially viable, it needs to address
these issues in some form, however inelegant it may be to have to
worry about them.
There are certainly ways around using &REST in a flavor system. But
they're bulky, cumbersome, and take time to write and debug. Time
that we needed to spend writing the body of our product. Our choice:
use &REST and be too slow and too large, or program around it, making
it a useless feature.
I'm not sure what the "correct" replacement/extension for it is, but
in my experience, &REST \can/ be too slow and too space consuming
for use in a real, deliverable product.
-- Stephen
∂06-Apr-88 1136 Common-Lisp-mailer
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 6 Apr 88 11:36:11 PDT
Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 6 Apr 88 09:41-EDT
Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 86292; 6 Apr 88 09:28:01-EDT
Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 98154; Wed 6-Apr-88 09:10:47-EST
Date: Wed, 6 Apr 88 09:10 est
From: mike%acorn@oak.lcs.mit.edu (mike@gold-hill.com any day now)
COMMENTS: NOTE %acorn@oak... WILL BECOME @GOLD-HILL.COM ANY DAY NOW
To: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Subject:
Cc: COMMON-LISP@SAIL.STANFORD.EDU
Date: Tue, 5 Apr 88 11:29:13 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Subject: Defstructs
Date: Tue, 5-APR-1988 10:55 MST
X-VMS-Mail-To: @COMMON-LISP
I'm trying to create structures on the fly. I have a problem with:
(defun test (&aux x)
(defstruct foo a b c)
(setf x (make-foo))
(setf (foo-a x) 1)
)
When TEST is interpreted, all is fine. When it is compiled the
function (foo-a) is undefined since it isn't created by defstruct
until run time. In my actual code FOO is a symbol that's build based
upon some args to TEST, therefore I can't simply put the defstruct at
the top level. Any ideas??
There are a few problems here. First, to compile (setf (foo-a x) 1)
you would have to have the structure predefined, since "setters" are
not even required to be callable functions by common lisp.
I have to ask why you have to do this in this fashion. It appears
you need to dynamically create named record "types". The way to do this
is not necessarily to evaluate a defstruct at run time.
I'd do it by inventing a meta-structure type.
(defstruct record
(name (gensym) :type symbol)
(slots #() :type vector))
or something like that. Then I'd use the copier to create new
instances, the constructor to create the initial "prototype" instance,
etc. You'd have to create your own predicates for recognizing
them and relating them.
This is unfortunately, exactly the way you'd have to do it
in a statically typed programming language.
...mike beckerle
Gold Hill
∂06-Apr-88 1225 Common-Lisp-mailer Re:
Received: from CAD.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 6 Apr 88 12:24:56 PDT
Date: Wed, 6 Apr 88 15:25:26 EDT
From: Mark.Perlin@CAD.CS.CMU.EDU
To: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA,
mike%acorn@LIVE-OAK.LCS.MIT.EDU
Subject: Re:
Cc: COMMON-LISP@SAIL.STANFORD.EDU
Sorry about that; misdirected mail.
∂06-Apr-88 1341 Common-Lisp-mailer Problems with setf and structures
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Apr 88 13:41:15 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 06 APR 88 13:40:56 PDT
Date: Wed, 6 Apr 88 13:39 PDT
From: Gregor.pa@Xerox.COM
Subject: Problems with setf and structures
To: "mike@gold-hill.com any day now" <mike%acorn@LIVE-OAK.LCS.MIT.EDU>
cc: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA, COMMON-LISP@SAIL.STANFORD.EDU
Fcc: BD:>Gregor>mail>outgoing-mail-2.text
In-Reply-To: The message of 6 Apr 88 07:10 PDT from "mike@gold-hill.com any day
now" <mike%acorn@LIVE-OAK.LCS.MIT.EDU>
Message-ID: <880406133904.2.GREGOR@SPIFF.parc.xerox.com>
Line-fold: no
Using CLOS, there is a better solution to your problem. Using CLOS and
taking advantage of one of the cleanup committee's proposals to cleanup
setf there is an even better solution.
Solution 1 - Using CLOS.
(defsetf foo-a set-foo-a)
(defsetf foo-b set-foo-b)
.
.
(defun test ()
(let (x)
(add-named-class
:name foo
:superclasses ()
:slot-specifications '((a :reader foo-a
:writer set-foo-a)
(b :reader foo-b
:writer set-foo-b)
.
.))
(setq x (make-instance 'foo))
(setf (foo-a x) 1)))
Solution 2 - Using CLOS and cleanup up setf
The basic difference is that you don't have to do the defsetfs. The
reason is that setf is defined to expand into a well-know function when
there hasn't been an explicit defsetf done.
(defun test ()
(let (x)
(add-named-class
:name foo
:superclasses ()
:slot-specifications '((a :accessor foo-a)
(b :accessor foo-b)
.
.))
(setq x (make-instance 'foo))
(setf (foo-a x) 1)))
-------
∂07-Apr-88 1045 Common-Lisp-mailer Re: Problems with SETF and structures
Received: from rutgers.edu by SAIL.Stanford.EDU with TCP; 7 Apr 88 10:45:08 PDT
Received: by rutgers.edu (5.54/1.15) with UUCP
id AA07408; Thu, 7 Apr 88 11:22:46 EDT
Date: Thu, 7 Apr 88 11:22:46 EDT
From: moss!whuts!davel@att.arpa
Message-Id: <8804071522.AA07408@rutgers.edu>
Received: by bellcore.bellcore.com (smail2.5)
id AA09765; 7 Apr 88 10:06:12 EDT (Thu)
To: common-lisp@sail.stanford.edu
Subject: Re: Problems with SETF and structures
Cc: davel@att.arpa
>Using CLOS, there is a better solution to your problem. Using CLOS and
>taking advantage of one of the cleanup committee's proposals to cleanup
>setf there is an even better solution.
>Solution 1 - Using CLOS.
>(defsetf foo-a set-foo-a)
>(defsetf foo-b set-foo-b)
.
.
>(defun test ()
> (let (x)
> (add-named-class
> :name foo
> :superclasses ()
> :slot-specifications '((a :reader foo-a
> :writer set-foo-a)
> (b :reader foo-b
> :writer set-foo-b)
> .
> .))
> (setq x (make-instance 'foo))
> (setf (foo-a x) 1)))
I fail to see the advantage of defining structures on the fly if
you must define their accessors up front. How can the method above
handle the situation if, for example, the slotnames or object name are
unknown at compile time. E.g.:
(DEFUN Make-Thingy (name slots)
(ADD-NAMED-CLASS :name name :superclasses ()
:slot-specifications slots)
(LET ((x (MAKE-INSTANCE name)))
(SETF <name-slot-1 x> 1)
x))
where <name-slot-1> is some notation for the accessor to the first slot
of this new structure.
>Solution 2 - Using CLOS and cleanup up setf
>The basic difference is that you don't have to do the defsetfs. The
>reason is that setf is defined to expand into a well-know function when
↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑↑↑↑
>there hasn't been an explicit defsetf done.
>(defun test ()
> (let (x)
> (add-named-class
> :name foo
> :superclasses ()
> :slot-specifications '((a :accessor foo-a)
> (b :accessor foo-b)
> .
> .))
> (setq x (make-instance 'foo))
> (setf (foo-a x) 1)))
I thought the idea behind add-named-class is to allow the creation on the
fly of new structure classes. Since the structure is not created until run
time, how can the compiler know at compile time how to expand
(setf (foo-a x) 1)?
If the compiler simply expands out the add-named-class at compile time,
thereby defining foo-a and its setf form, how does this differ from
(defstruct foo a b ...)
(or its equivalent in Flavors or LOOPS)?
As a further question, what is supposed to happen if two different functions
each are capable of defining structure FOO, and a third function uses a FOO-A
accessor? Depending upon which of the other two functions is run first, FOO-A
could refer to either of two different slots in the actual FOO structure.
What is a compiler supposed to do with that? How is the compiler supposed to
distinguish FOO-A, a FOO accessor defined by both functions, from FOO-B, which
is only defined by one of the functions, from FOO-C, which is a typo and
should generate at least a warning?
David Loewenstern
AT&T Bell Labs -- Whippany, NJ
{backbone}!rutgers!moss!whuts!davel -- or -- loewenst@paul.rutgers.edu
∂08-Apr-88 0001 Common-Lisp-mailer &Rest Lists
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 00:01:08 PDT
Received: by labrea.Stanford.EDU; Thu, 7 Apr 88 23:00:33 PST
Received: from bhopal.lucid.com by edsel id AA05582g; Thu, 7 Apr 88 23:53:02 PDT
Received: by bhopal id AA04002g; Thu, 7 Apr 88 23:53:51 PDT
Date: Thu, 7 Apr 88 23:53:51 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804080653.AA04002@bhopal.lucid.com>
To: jeff%aiva.edinburgh.ac.uk@nss.cs.ucl.ac.uk
Cc: Common-Lisp@sail.stanford.edu, @relay.cs.net:ELIOT@cs.umass.edu
In-Reply-To: Jeff Dalton's message of Sat, 2 Apr 88 18:54:38 bst <29307.8804021754@aiva.ed.ac.uk>
Subject: &Rest Lists
re: > FOO is a null function needed to prevent optimization.
> (dotimes (i 10000000) (cons 1 2)) is optimized to:
> (dotimes (i 10000000) nil) so:
Why isn't it optimized to just NIL?
Conjecture: it is an easy optimization to notice that a side-effect-free
function is being called in a place where no values are expected back (i.e.,
the call is only "for effects"); but it is much harder to have an analyzer
for tagbodies which usefully notices that they "don't do anything".
-- JonL --
∂08-Apr-88 0115 Common-Lisp-mailer &rest [discussion] replacement/addition
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 01:15:37 PDT
Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 00:14:59 PST
Received: from bhopal.lucid.com by edsel id AA05804g; Fri, 8 Apr 88 00:59:49 PDT
Received: by bhopal id AA04139g; Fri, 8 Apr 88 01:00:38 PDT
Date: Fri, 8 Apr 88 01:00:38 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804080800.AA04139@bhopal.lucid.com>
To: Sean.Engelson@SPICE.CS.CMU.EDU
Cc: common-lisp@sail.stanford.edu, spe@spice.cs.cmu.edu, ELIOT@cs.umass.edu,
gz@spt.entity.com
In-Reply-To: Sean.Engelson@SPICE.CS.CMU.EDU's message of Mon, 04 Apr 88 10:24:30 EDT <8804041428.AA16440@edsel.lucid.com>
Subject: &rest [discussion] replacement/addition
re: (defun fu (a &more-args)
(do-args (arg)
...code...
(moby-calculation a arg)
...more code...
))
VAX/NIL had an adequate solution that didn't involve the kind of hidden
state implicit in ideas similar to MacLisp's LEXPR's. There were two
indicators for functions with "more" arguments -- &RESTV and &RESTL --
the former produced a simple (general) vector of the remaining arguments
and the latter produced a list. The reason for this was that constructing
a stack-allocated vector out of the "remaining" arguments is something
that a stock-hardware implementation can do in essentially no time; but
re-structuring the "remaining" arguments into a stack-allocated list
takes time equivalent to ordinary listification of that many items.
So in VAX/NIL, &REST was *ambiguous* as to whether you got a vector or
list. The safe and portable style was to use &REST and access its
components only with sequence-like functions that accept either a vector
or a list (such as ELT, LENGTH, etc). Needless to say, all the appropriate
functions were generalized to take vectors as well as list -- APPLY, MAP
and so on. In some cases, we found it prudent to duplicate code --
once for the case when the &rest arg was a vector and once for when it was
a list. Here is a trivial example:
(defun + (&rest args &aux (result 0))
(if (listp args)
(dolist (x args) (incf result x))
(dovector (x args) (incf result x)))
result)
["trivial" since Common-Lisp MAP would be adequate here anyway].
We found it genuinely hard to justify the assertion that micro-differences
in timings (due to this design) could amount to anything important in system
performance. Hence it was very disappointing to see the Common Lisp votes
during '82 and '83 opt only for the version inspired by the special-purpose
hardware of the MIT LispMachine and its descendents.
It is also disappointing to see the amount of time (and mailer/diskspace)
wasted in defending a very quirky semantics for &rest lists -- that they
may be "shared" due to a potential optimization in APPLY. (Note that this
couldn't happen with &rest vectors). Despite what Will Clinger has argued,
I think Chris Eliot's reasoning is the norm accepted in the user community
-- namely that from the viewpoint of the callee, (foo 1 2 3) and
(apply #'foo '(1 2 3)) should be received identically. It is a gross
burden on the user to have to worry about hidden state in the implementation;
a burden which I should hope would be imposed only when there is *great* gain
to be had from doing so.
Gail Zacharias talked about the common idiom of simply doing a COPY-LIST on
every &rest argument, to insure some normalcy. Her reasoning seems, to me,
to bolster the case for those who claim that that CL semantics are deficient:
Subject: &REST Lists
Date: 24 Mar 88 12:23:15 EST (Thu)
From: gz@spt.entity.com (Gail Zacharias)
. . .
If Common Lisp doesn't require unshared &rest lists, then I think
it must provide a declarative version of this idiom so the COPY-LIST can
be portably avoided when it's redundant. Seems to me that the fact that
this is a common case where users find a need for conditionalization
indicates a real deficiency in Common Lisp's specification.
. . .
Of course, the problem isn't only the sharing of &rest lists, but the more
common flaw that they may, unannouncedly, have dynamic extent. By this, I
mean the bug where a stack-allocated &rest list can creep out into global
data structures, even though it will surely disappear when the frame that
created it returns. Allegedly, Symbolics is going to fix this bug in their
next release (and TI may have already fixed it?); but we are now five years
beyond the first CL specification!
Perhaps just one more word on what I think "*great* gain" would mean (in
the second paragraph back). For almost two months we have heard numerous
"experts" claim that this ability to share &rest lists is an important,
nay *critical*, component of optimization in certain implementations.
I just don't believe these conjectures. Eliot has done a "bang up" job
of presenting reasonable evidence that they can't be all that important;
so NOW, it is up to the advocates of this "optimization" to present some
hard evidence to the contrary. And PLEASE, NO MORE hypothetical cases of
what MIGHT occur, or what COULD CONCEIVABLY be; either "put up" with some
benchmark numbers from real applications (i.e., not just some fragments of
a few functions or a couple lines of microcode), or "shut up".
-- JonL --
∂08-Apr-88 0335 Common-Lisp-mailer
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 03:35:43 PDT
Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 02:35:13 PST
Received: from bhopal.lucid.com by edsel id AA06276g; Fri, 8 Apr 88 03:28:35 PDT
Received: by bhopal id AA04444g; Fri, 8 Apr 88 03:29:24 PDT
Date: Fri, 8 Apr 88 03:29:24 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804081029.AA04444@bhopal.lucid.com>
To: mike%acorn@LIVE-OAK.LCS.MIT.EDU
Cc: POTHIERS%TUVA.SAINET.MFENET@nmfecc.arpa, COMMON-LISP@sail.stanford.edu
In-Reply-To: mike@gold-hill.com any day now's message of Wed, 6 Apr 88 09:10 est <8804062003.AA27180@edsel.lucid.com>
re: There are a few problems here. First, to compile (setf (foo-a x) 1)
you would have to have the structure predefined, since "setters" are
not even required to be callable functions by common lisp.
Interestingly enough, one of the proposals before the X3J13 "Cleanup"
committee is to add the notion of SETF-FUNCTIONS to the language. This
would provide for every accessor name, a canonical updator name such that
if that updator name is fboundp, then it is the "callable function"
for doing the SETF.
It isn't immediately obvious from the "Cleanup" proposal, but a consequence
is that (SETF (FOO ...) Y) will never generate an error during compilation
or macroexpansion; for if there is no "SETF macro", then the canonical
updator name must be used, and it is quite permissible to supply the
defunition for that name at a later time (but of course, not later than
the first call to it!).
-- JonL --
∂08-Apr-88 0335 Common-Lisp-mailer &rest replacement/addition
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 03:35:12 PDT
Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 02:34:38 PST
Received: from bhopal.lucid.com by edsel id AA06261g; Fri, 8 Apr 88 03:17:06 PDT
Received: by bhopal id AA04429g; Fri, 8 Apr 88 03:17:54 PDT
Date: Fri, 8 Apr 88 03:17:54 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804081017.AA04429@bhopal.lucid.com>
To: Stever@waikato.s4cc.symbolics.com
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Stephen Robbins's message of Wed, 6 Apr 88 12:43 EDT <19880406164304.2.STEVER@JEWEL-CAVE.S4CC.Symbolics.COM>
Subject: &rest replacement/addition
re: . . . We found that &REST CONSing was
taking time and space we couldn't afford (the things it was doing to
the freelist! :-)
You didn't say what implementation of Common Lisp you were using. Some
do ordinary CONSing for &rest lists; some do "stack allocation"; and finally
others offer a DYNAMIC-EXTENT declaration so that you can choose, on a
per-function basis.
From your comment about the "freelist!", I would assume you were in an
implementation that did ordinary consing. I wonder how the selective
use of a DYNAMIC-EXTENT would have affected the project?
-- JonL --
∂08-Apr-88 1018 Common-Lisp-mailer LetRec?
Received: from SUMEX-AIM.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 10:18:43 PDT
Date: Fri, 8 Apr 88 10:18:58 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Subject: LetRec?
To: Common-Lisp@Sail.Stanford.EDU
Message-ID: <12388852434.13.RICE@SUMEX-AIM.Stanford.EDU>
Is there a good reason why this was omitted from CL?
Is it before the cleanup committee?
Rice.
-------
∂08-Apr-88 1204 Common-Lisp-mailer LetRec?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:03:05 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 8 Apr 88 15:01:24 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 8 Apr 88 15:01:21 EDT
Date: Fri, 8 Apr 88 15:02 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: LetRec?
To: James Rice <Rice@sumex-aim.stanford.edu>
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: <12388852434.13.RICE@SUMEX-AIM.Stanford.EDU>
Message-Id: <19880408190237.2.BARMAR@OCCAM.THINK.COM>
Date: Fri, 8 Apr 88 10:18:58 PDT
From: James Rice <Rice@sumex-aim.stanford.edu>
Is there a good reason why this was omitted from CL?
It wasn't. It is caled LABELS. It only supports function binding (like
FLET), but that is the only case where the distinction between LETREC
and LET* is useful.
∂08-Apr-88 1217 Common-Lisp-mailer Re: LetRec?
Received: from SUMEX-AIM.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:17:36 PDT
Date: Fri, 8 Apr 88 12:17:20 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Subject: Re: LetRec?
To: BarMar@Think.COM
cc: Common-Lisp@Sail.Stanford.EDU
Message-ID: <12388873983.13.RICE@SUMEX-AIM.Stanford.EDU>
Is there a good reason why this was omitted from CL?
It wasn't. It is caled LABELS. It only supports function binding (like
FLET), but that is the only case where the distinction between LETREC
and LET* is useful.
I beg to differ. I appreciate that I can declare recursive
local functions with Labels. I cannot, however refine recusive/
circular data structures with it. There seems to me to be a
good symetry argument in favour of non-function LetRec to
match with Labels. There also seems to be an argument in favour
of it in that those wanting to progam in a pure functional
style will not be able to declare circular structures in CL.
Rice.
-------
∂08-Apr-88 1243 Common-Lisp-mailer Re: LetRec?
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:43:51 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by Riverside.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 247044; Fri 8-Apr-88 15:42:30 EDT
Date: Fri, 8 Apr 88 15:42 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: LetRec?
To: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
cc: BarMar@Think.COM, Common-Lisp@SAIL.STANFORD.EDU
In-Reply-To: <12388873983.13.RICE@SUMEX-AIM.Stanford.EDU>
Message-ID: <19880408194257.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 8 Apr 88 12:17:20 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Is there a good reason why this was omitted from CL?
It wasn't. It is caled LABELS. It only supports function binding (like
FLET), but that is the only case where the distinction between LETREC
and LET* is useful.
I beg to differ. I appreciate that I can declare recursive
local functions with Labels. I cannot, however refine recusive/
circular data structures with it.
Perhaps I'm confused, but I don't think Scheme LETREC allows you to define
recursive or circular data structures. Could you provide a program example,
please?
∂08-Apr-88 1258 Common-Lisp-mailer LetRec
Received: from SUMEX-AIM.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 12:58:42 PDT
Date: Fri, 8 Apr 88 12:58:57 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Subject: LetRec
To: Common-Lisp@Sail.Stanford.EDU
Message-ID: <12388881557.13.RICE@SUMEX-AIM.Stanford.EDU>
Sorry to all of you who might have been confused by my
message. I was not thinking explicitly of Scheme's
Letrec. I was thinking of a general recursive let
construct, particularly for non-function objects, though
I see no reason why such a construct could not be used
for function objects too.
Rice.
-------
∂08-Apr-88 1357 Common-Lisp-mailer Re: LetRec?
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 13:57:18 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 APR 88 13:56:47 PDT
Date: Fri, 8 Apr 88 13:56:33 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: LetRec?
In-reply-to: <12388873983.13.RICE@SUMEX-AIM.Stanford.EDU>
To: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Cc: Common-Lisp@Sail.Stanford.EDU
Message-ID: <880408-135647-9308@Xerox>
I appreciate that I can declare recursive
local functions with Labels. I cannot, however refine recusive/
circular data structures with it. There seems to me to be a
good symetry argument in favour of non-function LetRec to
match with Labels. There also seems to be an argument in favour
of it in that those wanting to progam in a pure functional
style will not be able to declare circular structures in CL.
How will you implement it? More interestingly, how will you define its
semantics? In particular, while this human can tell that there's a solution to
the equation
x = (cons 1 x)
how is your compiler (or interpreter) going to distinguish that from
x = (+ 1 x)
or
x = (foo 1 x)
where ``foo'' is a function that I've written? I understand very well about the
usual least-fixed-point semantics for LETREC, but those fixed-points are usually
infinite or non-existent; how do you propose that the interpreter discover
representations of such fixed-points in general?
Pavel
∂08-Apr-88 1412 Common-Lisp-mailer &rest [discussion] replacement/addition
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 14:12:49 PDT
Received: from HAL.CAD.MCC.COM by MCC.COM with TCP; Fri 8 Apr 88 16:07:12-CDT
Received: from CHANGABANG.CAD.MCC.COM by HAL.CAD.MCC.COM via CHAOS with CHAOS-MAIL id 78623; Fri 8-Apr-88 16:07:05 CDT
Date: Fri, 8 Apr 88 16:04 CDT
From: William D. Gooch <gooch@CHANGABANG.CAD.MCC.COM>
Subject: &rest [discussion] replacement/addition
To: edsel!jonl%labrea.Stanford.EDU@MCC.COM
cc: common-lisp%sail.stanford.edu@MCC.COM, spe%spice.cs.cmu.edu@MCC.COM,
ELIOT%cs.umass.edu@MCC.COM, gz%spt.entity.com@MCC.COM
In-Reply-To: <8804080800.AA04139@bhopal.lucid.com>
Message-ID: <880408160418.1.GOOCH@CHANGABANG.CAD.MCC.COM>
Reply-To: gooch@MCC.COM
Postal-address: MCC-CAD 3.8108
Business-phone: (512) 338-3661
I have a simple anagram generator which, being highly recursive, is an
interesting test of &rest behavior. (If you already believe me, you may
skip to the tables at the end of this message.) This is a toy program,
but it may provide some insight.
The approach taken is to find a word made up of characters from the
input string, then recur on the unused characters. One argument to the
recursive call is a list of previously found words; when an anagram that
exactly uses all the characters is identified, it is saved and/or
printed from within the innermost stack frame in the recursion.
The previous-words argument data can be dealt with in a straightforward
fashion using &rest. For example (oversimplified for the purpose of
illustration):
(defun anagrams (string &rest previous-words)
(let ((chars (unused-characters string previous-words)))
(if chars
;; there are unused characters left
(let ((new-word (find-word chars)))
(when new-word
;; found a new word
(apply #'anagrams string new-word previous-words)
;; if no new word could be found, just return
))
;; all characters are used by previous-words, we have a weiner
(save-and/or-print-anagram string previous-words)
)))
Note that there are no undesirable side-effects of list sharing since
the list isn't changed except when it grows at the time of recursion.
The same end can of course be accomplished by other means (see below).
The runtime results in the table below were obtained using the form
(without-interrupts (time (do-anagrams "<input string>" NIL))) -- the
final argument of NIL specifies that results should be saved in a data
structure rather than printed as they are identified.
I ran the test with some variations on argument passing: (1) no use of
&rest in the code at all. Instead I used a list whose length equalled
the number of characters in the input string, added new words via (setf
(car (nthcdr nwords previous-words)) new-word) and passed it through as
a single argument on recursion. Variation (2) used &rest in the fashion
shown above, with the default behavior (on a Symbolics, this is stack
consing). For variation (3), I just added the form (setf previous-words
(copy-list previous-words)) at the beginning of the function to simulate
a gratuitously-consing &rest implementation.
Anagram timings -- Symbolics Genera 7.1 on a 3600 running 3670 microcode
input string code version runtime (sec) list consing (words)
-------------------------------------------------------------------------
hi there (1) no &rest 14.38 144
hi there (2) &rest, no copy 14.29 144
hi there (3) &rest, copy 14.35 1428
ian gooch (1) no &rest 138.7 464
ian gooch (2) &rest, no copy 138.5 464
ian gooch (3) &rest, copy 138.7 6913
Two more variations are also interesting. To reorder the characters
without consing, it was convenient to add some intermediate levels of
recursion which don't appear in the above example. When I use &rest and
apply for the reordering function as well as in the function anagrams as
shown above, I get the following:
input string code version runtime (sec) list consing (words)
-------------------------------------------------------------------------
hi there all &rest, no copy 14.28 144
hi there all &rest, copy 14.77 6814
ian gooch all &rest, no copy 138.4 464
ian gooch all &rest, copy 140.0 30777
paul gooch all &rest, no copy 1018 820
paul gooch all &rest, copy 1020 33770
I would include more results, but they are all pretty consistent.
Draw your own conclusions. I'm not advocating a particular point of
view here, although I think &rest should always have a form which allows
its user to control consing, regardless of how performance might or
might not be affected.
-- William D. Gooch
∂08-Apr-88 1503 Common-Lisp-mailer Re: LetRec?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:03:15 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 8 Apr 88 18:01:31 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 8 Apr 88 18:01:26 EDT
Date: Fri, 8 Apr 88 18:02 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: LetRec?
To: James Rice <Rice@sumex-aim.stanford.edu>
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: <12388873983.13.RICE@SUMEX-AIM.Stanford.EDU>
Message-Id: <19880408220237.5.BARMAR@OCCAM.THINK.COM>
Date: Fri, 8 Apr 88 12:17:20 PDT
From: James Rice <Rice@sumex-aim.stanford.edu>
Is there a good reason why this was omitted from CL?
It wasn't. It is caled LABELS. It only supports function binding (like
FLET), but that is the only case where the distinction between LETREC
and LET* is useful.
I beg to differ. I appreciate that I can declare recursive
local functions with Labels. I cannot, however refine recusive/
circular data structures with it. There seems to me to be a
good symetry argument in favour of non-function LetRec to
match with Labels. There also seems to be an argument in favour
of it in that those wanting to progam in a pure functional
style will not be able to declare circular structures in CL.
I don't think you can create circular structures with Scheme's LETREC,
either. The reason is that you would actually have to evaluate the
variable while creating the structure, and the values of the variables
being bound are undefined until all the initializations have completed.
In the case of procedures this is OK, because you don't actually
evaluate the procedure values until you invoke the procedure; all that
is needed in order to create the procedure is that the environment be
created with a placeholder for the procedure. So,
(letrec ((factorial (lambda (x)
(if (< 2 x) 1
(* x (factorial (- x 1)))))))
(factorial 100))
works, but
(letrec ((circular (list* 1 2 3 4 circular)))
circular)
is undefined, because the value of CIRCULAR is undefined at the time the
LIST* form is being evaluated.
In order to create circular structure, you have to do something like
(let ((circular (list 1 2 3 4)))
(setf (cdr (last circular)) circular)
circular)
I don't know how to do this kind of thing in a purely functional style.
∂08-Apr-88 1531 Common-Lisp-mailer &rest [discussion] replacement/addition
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:31:22 PDT
Received: from Think.COM by MCC.COM with TCP; Fri 8 Apr 88 17:30:28-CDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 8 Apr 88 18:28:48 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 8 Apr 88 18:28:44 EDT
Date: Fri, 8 Apr 88 18:29 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: &rest [discussion] replacement/addition
To: gooch@mcc.com
Cc: edsel!jonl%labrea.Stanford.EDU@mcc.com,
common-lisp%sail.stanford.edu@mcc.com, spe%spice.cs.cmu.edu@mcc.com,
ELIOT%cs.umass.edu@mcc.com, gz%spt.entity.com@mcc.com
In-Reply-To: <880408160418.1.GOOCH@CHANGABANG.CAD.MCC.COM>
Message-Id: <19880408222959.6.BARMAR@OCCAM.THINK.COM>
I noticed you didn't try the following version. This is identical to
the version you included in your message, except that it takes the
previous words as a single argument rather than as an &REST argument.
One definite advantage of this version is that it won't exceed
CALL-ARGUMENTS-LIMIT if it recurses deeply.
(defun anagrams (string &optional previous-words)
(let ((chars (unused-characters string previous-words)))
(if chars
;; there are unused characters left
(let ((new-word (find-word chars)))
(when new-word
;; found a new word
(anagrams string (cons new-word previous-words))
;; if no new word could be found, just return
))
;; all characters are used by previous-words, we have a weiner
(save-and/or-print-anagram string previous-words)
)))
∂08-Apr-88 1541 Common-Lisp-mailer LetRec
Received: from SUMEX-AIM.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:40:53 PDT
Date: Fri, 8 Apr 88 15:41:00 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Subject: LetRec
To: Common-Lisp@Sail.Stanford.EDU
Message-ID: <12388911060.13.RICE@SUMEX-AIM.Stanford.EDU>
In order to create circular structure, you have to do something like
(let ((circular (list 1 2 3 4)))
(setf (cdr (last circular)) circular)
circular)
I don't know how to do this kind of thing in a purely functional style.
Yes, it's clear that in order to implement a letrec, which would allow
you to express:
(letrec ((circular (list 1 2 3 circular))
...circular)
Something would have to be fixed up after the structure was created.
I have no idea how one would best implement this but I would assume
that the compiler would substitute all all appropriate references to
the named object with some sort of forwaring cell, which would be
smashed to point to the whole object after it was created.
I also know of no way that a pure functional program can perform
these fixups. That's why I thought that it was important for the
system to provide this.
If I'm being totally brain damaged here then I'm sorry. We can,
after all get back to those messages about &Rest args.
Noone, yet, seems to have said that such a letrec would be a totally
worthless thing. Equally, noone has been saying things like "well,
it's too late/hard to put it into CL."
Rice.
-------
∂08-Apr-88 1601 Common-Lisp-mailer LetRec
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 15:59:43 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 8 Apr 88 18:58:12 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 8 Apr 88 18:58:09 EDT
Date: Fri, 8 Apr 88 18:59 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: LetRec
To: James Rice <Rice@sumex-aim.stanford.edu>
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: <12388911060.13.RICE@SUMEX-AIM.Stanford.EDU>
Message-Id: <19880408225924.8.BARMAR@OCCAM.THINK.COM>
Date: Fri, 8 Apr 88 15:41:00 PDT
From: James Rice <Rice@sumex-aim.stanford.edu>
Yes, it's clear that in order to implement a letrec, which would allow
you to express:
(letrec ((circular (list 1 2 3 circular))
...circular)
Something would have to be fixed up after the structure was created.
I have no idea how one would best implement this but I would assume
that the compiler would substitute all all appropriate references to
the named object with some sort of forwaring cell, which would be
smashed to point to the whole object after it was created.
While that might work for simple data structure creation, there's just
no way it could be generalized. What does:
(letrec ((value (+ value 3)))
value)
mean? Or how about?
(letrec ((circular (list* 1 2 3 (mapcar #'(lambda (x) (* x 2)) circular))))
circular)
return? It looks like it should return something like
(1 2 3
2 4 6
4 8 12
8 16 24
...)
but I don't think it is actually possible.
∂08-Apr-88 1617 Common-Lisp-mailer LetRec
Received: from SUMEX-AIM.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 16:17:06 PDT
Date: Fri, 8 Apr 88 16:16:43 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Subject: LetRec
To: BarMar@Think.Com
cc: Common-Lisp@Sail.Stanford.EDU
Message-ID: <12388917560.13.RICE@SUMEX-AIM.Stanford.EDU>
Mmmm, I see what you're getting at. Maybe it's a wimp-out
but how about:
It is an error to use the named structure in the definition
of a letrec variable as an argument to a strict operator
during the evaluation of its definition.
e.g. (letrec ((foo (+ 1 foo))) <---- error
(letrec ((bar (cons 42 bar))) <--- ok.
Rice.
-------
∂08-Apr-88 1724 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 8 Apr 88 17:24:47 PDT
Received: from BRAHMA.ACA.MCC.COM ([128.62.12.110].#Internet) by MCC.COM with TCP; Fri 8 Apr 88 19:24:00-CDT
Date: Fri, 8 Apr 88 19:21 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: LetRec the way you want it IS in Common-lisp
To: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
cc: BarMar@Think.Com, Common-Lisp@Sail.Stanford.EDU
In-Reply-To: <12388917560.13.RICE@SUMEX-AIM.Stanford.EDU>
Message-ID: <19880409002104.5.GUMBY@BRAHMA.ACA.MCC.COM>
Date: Fri, 8 Apr 88 16:16:43 PDT
From: James Rice <Rice@SUMEX-AIM.Stanford.EDU>
Mmmm, I see what you're getting at. Maybe it's a wimp-out
but how about:
It is an error to use the named structure in the definition
of a letrec variable as an argument to a strict operator
during the evaluation of its definition.
e.g. (letrec ((foo (+ 1 foo))) <---- error
(letrec ((bar (cons 42 bar))) <--- ok.
In common-lisp you can get the reader to do this for you:
==> (prog1 nil (setf foo '#1=(a . #1#)))
nil
==> (first foo)
a
==> (second foo)
a
==> (third foo)
a
∂08-Apr-88 1915 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 8 Apr 88 19:15:35 PDT
Received: by labrea.Stanford.EDU; Fri, 8 Apr 88 18:14:32 PST
Received: from bhopal.lucid.com by edsel id AA10081g; Fri, 8 Apr 88 19:08:00 PDT
Received: by bhopal id AA07844g; Fri, 8 Apr 88 19:08:52 PDT
Date: Fri, 8 Apr 88 19:08:52 PDT
From: Jim McDonald <edsel!jlm@labrea.Stanford.EDU>
Message-Id: <8804090208.AA07844@bhopal.lucid.com>
To: labrea!Gumby%MCC.COM@labrea.Stanford.EDU
Cc: labrea!Common-Lisp%Sail.Stanford.EDU@labrea.Stanford.EDU
Subject: LetRec the way you want it IS in Common-lisp
> In common-lisp you can get the reader to do this for you:
>
> ==> (prog1 nil (setf foo '#1=(a . #1#)))
> nil
> ==> (first foo)
> a
> ==> (second foo)
> a
> ==> (third foo)
> a
That was my first reaction, but this creates a global structure.
I think the goal is to get a dynamically generated recursive
structure. You could do something awful like
(let ((foo (eval (read-from-string "'#1=(a . #1#)"))))
...)
but this seems too bletcherous to suggest as a canonical solution.
Perhaps one could extend backquote to include something like the #n=
feature of the reader. (Perhaps this feature is already in backquote
and I don't know about it?) The following unhappy syntax should not
be that hard to implement:
(let ((foo `,=1=(a ,.=1=)))
...)
Someone who cares could improve on it.
To return to the original question:
Assuming that backquote (or whatever) could give you dynamically
created recursive data structures, and that recursive forms in general
are impossible to handle, is there something in-between that you want?
jlm
∂09-Apr-88 0528 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Apr 88 05:28:43 PDT
Received: by labrea.Stanford.EDU; Sat, 9 Apr 88 04:28:15 PST
Received: from bhopal.lucid.com by edsel id AA11679g; Sat, 9 Apr 88 05:20:00 PDT
Received: by bhopal id AA08970g; Sat, 9 Apr 88 05:20:53 PDT
Date: Sat, 9 Apr 88 05:20:53 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804091220.AA08970@bhopal.lucid.com>
To: Gumby@mcc.com
Cc: Rice@sumex-aim.stanford.edu, BarMar@think.com,
Common-Lisp@sail.stanford.edu
In-Reply-To: David Vinayak Wallace's message of Fri, 8 Apr 88 19:21 CDT <19880409002104.5.GUMBY@BRAHMA.ACA.MCC.COM>
Subject: LetRec the way you want it IS in Common-lisp
re: In common-lisp you can get the reader to do this for you:
==> (prog1 nil (setf foo '#1=(a . #1#)))
I've been sitting on the sideline of this discussion wondering what the
heck anyone expected of LetRec in the line of "recursive" data structures.
It seemed just too obvious that the originator of this question had
overlooked the #= and ## notation of the Common Lisp Reader for expressing
circular *constants*.
Now, maybe what he wanted was a freshly-consed-up copy of some circular
structure; say, something equivalent to `#1=(a . ,#1#). Just by
coincidence, the way Lucid's reader implements the #= and ## stuff is
awfully close to the way one might naively implement backquote; so with
very little more work this notation could actually do the expected thing!
Looks pretty "functional" to me!
[On the other hand, although this sort of data-pattern is just what a
programmer might like, I'm not sure that the folks who thought this
suggestion meant solving simultaneous recursive equations were way off
base. Give that man a turing machine. Complete with halting problem.]
-- JonL --
∂09-Apr-88 2212 Common-Lisp-mailer LetRec
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 9 Apr 88 22:12:20 PDT
Return-Path: <barmar@Think.COM>
Received: from fafnir.think.com by Think.COM; Sun, 10 Apr 88 01:10:47 EDT
Received: by fafnir.think.com; Sun, 10 Apr 88 01:10:45 EDT
Date: Sun, 10 Apr 88 01:10:45 EDT
From: barmar@Think.COM
Message-Id: <8804100510.AA05684@fafnir.think.com>
To: Rice@sumex-aim.stanford.edu
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: James Rice's message of Fri, 8 Apr 88 16:16:43 PDT <12388917560.13.RICE@SUMEX-AIM.Stanford.EDU>
Subject: LetRec
Date: Fri, 8 Apr 88 16:16:43 PDT
From: James Rice <Rice@sumex-aim.stanford.edu>
Mmmm, I see what you're getting at. Maybe it's a wimp-out
but how about:
It is an error to use the named structure in the definition
of a letrec variable as an argument to a strict operator
during the evaluation of its definition.
What is the definition of "strict operator"? Is a user-defined
function a strict operator?
e.g. (letrec ((foo (+ 1 foo))) <---- error
(letrec ((bar (cons 42 bar))) <--- ok.
In this case, I don't think this facility is appropriate for the
standard language. Are there any Lisp implementations that have such
a facility? If not, I think it would be a bad idea to suddenly thrust
it into the standard.
∂10-Apr-88 0702 Common-Lisp-mailer &rest arguments
Received: from ucbvax.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 10 Apr 88 07:02:44 PDT
Received: by ucbvax.Berkeley.EDU (5.59/1.28)
id AA04531; Sun, 10 Apr 88 01:22:36 PDT
From: trwrb!smpvax1!jrg@ucbvax.Berkeley.EDU
Received: by trwrb (5.51/1.36)
id AA21005; Fri, 8 Apr 88 17:10:51 PDT
Date: Fri, 8 Apr 88 17:10:51 PDT
Message-Id: <8804090010.AA21005@trwrb>
To: common-lisp@sail.stanford.edu
Subject: &rest arguments
For Inference commercial products written in Common Lisp where stack
consing of &rest is not supported, we do not use &rest arguments. The
overriding consideration is to avoid generating the cons garbage of
the &rest argument. We NEVER maintain pointers to conses in &rest
arguments outside the extent of the function call that caused the &rest
argument to be set up. We do use &rest arguments where stack consing
of the &rest argument is available; in fact, this is fast becoming a
de facto lisp language requirement for our code -- we've pointed this
out to numerous Lisp vendors.
So, I advocate adding a declaration to Common Lisp much like the
DYNAMIC-EXTENT declaration already available in Lucid Lisp. Functionality
like this is, I believe, mandatory for a Lisp to be viable as the basis
for a commercial software product.
As for APPLY and &rest arg copying or sharing, we'd never use such a
construct in our code anyway, so I don't care. I believe that not
guaranteeing the sharing is the best approach, if you want an opinion.
In general, APPLY is just too slow. We've avoided it for mini-object
systems used internally for this reason (that is, to call methods from
a generic function).
--Joe
∂11-Apr-88 1124 Common-Lisp-mailer LetRec
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 11 Apr 88 11:24:50 PDT
Return-Path: <gls@Think.COM>
Received: from kali.think.com by Think.COM; Mon, 11 Apr 88 14:23:11 EDT
Received: by kali.think.com; Mon, 11 Apr 88 14:23:08 EDT
Date: Mon, 11 Apr 88 14:23:08 EDT
From: gls@Think.COM
Message-Id: <8804111823.AA05656@kali.think.com>
To: Rice@sumex-aim.stanford.edu
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: James Rice's message of Fri, 8 Apr 88 12:58:57 PDT <12388881557.13.RICE@SUMEX-AIM.Stanford.EDU>
Subject: LetRec
Date: Fri, 8 Apr 88 12:58:57 PDT
From: James Rice <Rice@sumex-aim.stanford.edu>
Sorry to all of you who might have been confused by my
message. I was not thinking explicitly of Scheme's
Letrec. I was thinking of a general recursive let
construct, particularly for non-function objects, though
I see no reason why such a construct could not be used
for function objects too.
Rice.
-------
See, for example, the paper by F. Lockwood Morris and Jerald S. Schwarz,
"Computing Cyclic List Structures" in the Proceedings of the 1980 Lisp
Conference (which has been reprinted by ACM).
--Guy
∂11-Apr-88 1130 Common-Lisp-mailer LetRec the way you want it IS in Common-lisp
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 11 Apr 88 11:29:53 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA17400; Mon, 11 Apr 88 14:29:23 EDT
From: mcvax!pilatus!ceb@uunet.UU.NET
Received: by mcvax.cwi.nl; Sun, 10 Apr 88 16:53:25 +0200 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA13469; Sun, 10 Apr 88 16:18:19 +0200
Date: Sun, 10 Apr 88 16:18:19 +0200
Message-Id: <8804101418.AA13469@cernvax.uucp>
To: edsel!jonl@uunet.UU.NET, edsel!jlm@uunet.UU.NET
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Sat, 9 Apr 88 05:20:53 PDT
Subject: LetRec the way you want it IS in Common-lisp
Date: Fri, 8 Apr 88 19:08:52 PDT
From: Jim McDonald <cernvax!mcvax!edsel!jlm>
. . .
To return to the original question:
Assuming that backquote (or whatever) could give you dynamically
created recursive data structures, and that recursive forms in general
are impossible to handle, is there something in-between that you want?
Date: Sat, 9 Apr 88 05:20:53 PDT
From: Jon L White <cernvax!mcvax!edsel!jonl>
. . .
Now, maybe what he wanted was a freshly-consed-up copy of some circular
structure; say, something equivalent to `#1=(a . ,#1#). . . .
[On the other hand, although this sort of data-pattern is just what a
programmer might like, I'm not sure that the folks who thought this
suggestion meant solving simultaneous recursive equations were way off
base. Give that man a turing machine. Complete with halting problem.]
I would find it useful to have dynamic functional specification of
non-arborescent structures in CL, but the problems are indeed large.
In response to jlm's question about something in-between, the
following suggestion is made:
It was mentioned earlier that any scheme of this type would only work
for "special" operators (I forget the exact adjective used, but it was
later stamped as inappropriate or unclear.) The nature of this
speciality seem to me to be best described as "encapsulating". A
function is encapsulating when it takes its arguments and buries them
in some topological structure in memory (including, but not limited
to, cons-cell spaghetti) without interfering with them procedurally in
any way. The functions cons and list are encapsulating, but +, -,
etc. are not, since they feed their arguments back into some
procedural operation. For simplicity's sake, functions such as car,
cdr, and their descendants should be considered as non-encapsulating,
although I haven't ruled out for myself the possibility of getting
around *their* particular kind of procedural hacking with a modicum of
cleverness.
This concept in place, in implementing this feature in the context of
something like backquote, it would then be simple only to permit
references to recursive reference points when these appear as
arguments to encapsulating functions, and to permit these to refer
only to constants, or other encapsulating functions. There
would, of course, have to be a "(declare (encapsulating-function
<myfunc> . . .))" form to permit users to identify their own functions
having this property (and to shoot themselves in the foot if they
lie).
The other implementational hurdles then seem surmountable *but* you
would have to change the order in which encapsulating functions are
evaluated - it would no longer be acceptable to grind through its
arguments first. However, it seems that under the definition of
encapsulability, this will always be legal, and you will still be able
to satisfy the thrust of the original suggestion.
From shipboard, this seems a simple yet reasonably robust way to get
beyond the "impossibility of general recursive structures" Muffel.
Whether it is worth adding to the language depends on how hard it is
to implement, and how much additional cognitive clutter the language
can stand.
ceb
∂11-Apr-88 1341 Common-Lisp-mailer LetRec
Received: from SAIL.Stanford.EDU by SAIL.Stanford.EDU with TCP; 11 Apr 88 13:40:40 PDT
Date: Mon, 11 Apr 88 13:35:53
X-Date-last-edited: 1988 April 11 13:35:53 PDT (=GMT-7hr)
X-Date-posted: 1988 April 11 13:38:04 PDT (=GMT-7hr)
From: Robert Elton Maas <REM%IMSSS@SAIL.Stanford.EDU>
To:common-lisp@sail.stanford.edu
CC:edsel!jonl@uunet.UU.NET,edsel!jlm@uunet.UU.NET
Subject:LetRec
<M> From: mcvax!pilatus!ceb@uunet.UU.NET
<M> It was mentioned earlier that any scheme of this type would only work
<M> for "special" operators (I forget the exact adjective used, but it was
<M> later stamped as inappropriate or unclear.) The nature of this
<M> speciality seem to me to be best described as "encapsulating". A
<M> function is encapsulating when it takes its arguments and buries them
<M> in some topological structure in memory (including, but not limited
<M> to, cons-cell spaghetti) without interfering with them procedurally in
<M> any way. The functions cons and list are encapsulating, but +, -,
<M> etc. are not, since they feed their arguments back into some
<M> procedural operation.
I nominate using BBN/UCI-lisp editor terminology here, namely "embed".
CONS and LIST are embedding functions.
<M> For simplicity's sake, functions such as car,
<M> cdr, and their descendants should be considered as non-encapsulating,
They do the opposite. Again I nominate using BBN/UCI-lisp editor
terminology, namely "extract". CAR and NTH (in regard to its list
argument) are extracting functions.
IDENTITY is both the trivial embedding and the trivial extracting
function. To avoid recursion loops we should require nontrivial (strict)
embedding functions for LetRec.
<M> (declare (encapsulating-function <myfunc> . . .))
(declare (embedding-function <myfunc> . . .))
Because "encapsulating" is a more elaborate concept usually, having to do
with closures and abstraction etc., I prefer to avoid that term for the
simple structural concept we're discussing here.
<M> ... to permit users to identify their own functions having this property
<M> (and to shoot themselves in the foot if they lie).
(:- Or cut off their damn heels :-)
(N.B. That's from a comedy album played on KFAT dealing with chain saw.)
<M> The other implementational hurdles then seem surmountable *but* you
<M> would have to change the order in which encapsulating functions are
<M> evaluated - it would no longer be acceptable to grind through its
<M> arguments first.
In this case of LetRec, have low-level mechanism (part of LetRec) pass a
dummy forwarding cell, evaluate normally, then after return more
low-level LetRec mechanism do the replacement for the true value to
create circularity. This localizes the implementation work to LetRec
itself, not random functions such as CONS, thus it can be done outside a
Scheme-style lazy-evaluator within a normal evaluator.
<M> Whether it is worth adding to the language depends on how hard it is
<M> to implement, and how much additional cognitive clutter the language
<M> can stand.
More importantly, it shouldn't become part of CLtL until after it has
been implemented by at least several experimental implementations to work
out the bugs in the basic design and see if it really is useful.
∂11-Apr-88 1434 Common-Lisp-mailer Question on terminology
Received: from tully.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 11 Apr 88 14:34:15 PDT
Received: by tully.Berkeley.EDU (5.57/1.25)
id AA01491; Mon, 11 Apr 88 14:34:39 PDT
From: hilfingr%tully.Berkeley.EDU@ginger.Berkeley.EDU (Paul Hilfinger)
Message-Id: <8804112134.AA01491@tully.Berkeley.EDU>
To: common-lisp@sail.stanford.edu
Subject: Question on terminology
Date: Mon, 11 Apr 88 14:34:36 PDT
[Forgive me if I missed the following point in the volume of articles
on letrec].
In the current debate about letrec, I've noticed many references to
circular data structures as "recursive." With all due respect, is
this a proper use of the term? I've usually seen the term "recursive
data TYPE"" used to refer to types that are recursively defined, as in
"a list is either null or comprises a head of arbitrary type and a
tail that is a list." Alternatively, I have seen recursive data
structures defined as those that contain components having the same
type ("same type", not "pointers to objects of the same type",
although of course, pointers might be used in the implementation).
C.A.R. Hoare, among others, have used the latter terminology (which,
because it does not mention "pointers", actually excludes circular
structures, since an object cannot contain itself.)
Even discounting the definitions of such people as Hoare---who is
famous but far outside the Lisp community---I don't like the equation
of "recursive" and "circular" for the simple reason that MY recursive
programs, at least, eventually terminate. (Usually)
Paul Hilfinger
hilfingr@ginger.Berkeley.EDU
∂12-Apr-88 0654 Common-Lisp-mailer &rest [discussion] replacement/addition
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 12 Apr 88 06:54:18 PDT
Received: from HAL.CAD.MCC.COM by MCC.COM with TCP; Tue 12 Apr 88 08:51:03-CDT
Received: from CHANGABANG.CAD.MCC.COM by HAL.CAD.MCC.COM via CHAOS with CHAOS-MAIL id 78811; Tue 12-Apr-88 08:47:48 CDT
Date: Tue, 12 Apr 88 08:48 CDT
From: William D. Gooch <gooch@CHANGABANG.CAD.MCC.COM>
Subject: &rest [discussion] replacement/addition
To: barmar%Think.COM@MCC.COM
cc: edsel!jonl%labrea.Stanford.EDU@mcc.com,
common-lisp%sail.stanford.edu@mcc.com, spe%spice.cs.cmu.edu@mcc.com,
ELIOT%cs.umass.edu@mcc.com, gz%spt.entity.com@mcc.com
In-Reply-To: <19880408222959.6.BARMAR@OCCAM.THINK.COM>
Message-ID: <880412084804.2.GOOCH@CHANGABANG.CAD.MCC.COM>
Reply-To: gooch@MCC.COM
Postal-address: MCC-CAD 3.8108
Business-phone: (512) 338-3661
Date: Fri, 8 Apr 88 18:29 EDT
From: Barry Margolin <barmar@Think.COM>
I noticed you didn't try the following version. This is identical to
the version you included in your message, except that it takes the
previous words as a single argument rather than as an &REST argument.
One definite advantage of this version is that it won't exceed
CALL-ARGUMENTS-LIMIT if it recurses deeply.
I had run this version before, but neglected to include it in the timing
runs.
input string code version runtime (sec) list consing (words)
-------------------------------------------------------------------------
hi there no &rest, cons 14.25 1280
ian gooch no &rest, cons 138.3 4626
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Date: Sat, 9 Apr 88 12:35 EDT
From: ELIOT%cs.umass.edu@RELAY.CS.NET
...I think &rest should always have a form which allows
its user to control consing, regardless of how performance might or
might not be affected.
After ALL the discussion about this topic, it seems that this claim should
be justified, if it is going to be made at all. I think there is general
agreement that the only reason why the user might need control over consing
&rest lists is the effect on performance.
You're right. I guess I didn't mean that the way it came out.
Performance is the object, but my current assumption is that consing
must adversely affect overall performance.
Your data does not seem
to show such an effect. Another experiment you could try would be to
run the same examples many times (100 or 1000 times) with the
garbage collector on. The idea is to do so much consing that the GC must
run. That way you can claim that the timings include the GC overhead.
Good idea. Results later.
If you do that and still get practically the same runtime results for all
of the different versions, then I think you should conclude that the runtime
of your example does not depend upon how the &rest list is handled.
-- William D. Gooch
∂13-Apr-88 1100 Common-Lisp-mailer Re: &rest [discussion] replacement/addition
Received: from ti.com by SAIL.Stanford.EDU with TCP; 13 Apr 88 11:00:27 PDT
Received: by ti.com id AA29855; Wed, 13 Apr 88 12:58:18 CDT
Received: from Islington-Terrace by tilde id AA05452; Wed, 13 Apr 88 12:54:53 CDT
Message-Id: <2785945967-1737834@Islington-Terrace>
Sender: pf@Islington-Terrace.csc.ti.com
Date: Wed, 13 Apr 88 12:52:47 CDT
From: Paul Fuqua <pf@ti-csl.csc.ti.com>
To: common-lisp@sail.stanford.edu
Subject: Re: &rest [discussion] replacement/addition
In-Reply-To: Msg of 8 Apr 88 20:43:52 GMT from Jon L White <edsel!jonl@LABREA.STANFORD.EDU>
Date: Friday, April 8, 1988 3:43pm (CDT)
From: Jon L White <edsel!jonl at LABREA.STANFORD.EDU>
Subject: &rest [discussion] replacement/addition
Of course, the problem isn't only the sharing of &rest lists, but the more
common flaw that they may, unannouncedly, have dynamic extent. By this, I
mean the bug where a stack-allocated &rest list can creep out into global
data structures, even though it will surely disappear when the frame that
created it returns. Allegedly, Symbolics is going to fix this bug in their
next release (and TI may have already fixed it?); but we are now five years
beyond the first CL specification!
We fixed it for Release 3, which came out some time ago. We use a separate
internal data type for stack-lists, which, when the list is returned from a
function or stored into the heap, is noticed and causes the list to copied
out of the stack. There's other hair to preserve EQness and to cope with
stack-groups and special-bindings.
As a matter of fact, I asked about the problem of APPLYing a function with a
&REST arg back when I was doing the function-calling microcode. The easy
approach was to spread the list and re-collect it into a stack-list, which
would avoid both the sharing and the consing, but we decided at the time to
avoid the spreading overhead. If the standard says not to share, we'll
spread and re-collect.
Incidentally, our implementation of keyword arguments also uses a &REST arg,
so &KEY implies &REST internally. Did that appear in the statistics? I
don't know if other implementations do the same.
The general rule around here is, "Don't modify a list if you don't know where
it came from." Many constants in our implementation end up in read-only
areas, and there are other instances of sharing than APPLY/&REST, so it's
seen as a bad idea to use destructive operations on random data objects.
pf
Paul Fuqua
Texas Instruments Computer Science Center, Dallas, Texas
CSNet: pf@csc.ti.com (ARPA too, eventually)
UUCP: {smu, texsun, im4u, rice}!ti-csl!pf
∂14-Apr-88 0053 Common-Lisp-mailer LetRec
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 14 Apr 88 00:53:39 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA18873; Thu, 14 Apr 88 03:53:17 EDT
From: mcvax!pilatus!ceb@uunet.UU.NET
Received: by mcvax.cwi.nl; Thu, 14 Apr 88 08:27:15 +0200 (MET)
Received: by cernvax.uucp (1.2/Ultrix2.0-B)
id AA25175; Wed, 13 Apr 88 15:06:39 +0200
Date: Wed, 13 Apr 88 15:06:39 +0200
Message-Id: <8804131306.AA25175@cernvax.uucp>
To: REM@sail.stanford.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Robert Elton Maas's message of Mon, 11 Apr 88 13:35:53
Subject: LetRec
Date: Mon, 11 Apr 88 13:35:53
X-Date-Last-Edited: 1988 April 11 13:35:53 PDT (=GMT-7hr)
X-Date-Posted: 1988 April 11 13:38:04 PDT (=GMT-7hr)
From: Robert Elton Maas <cernvax!mcvax!SAIL.Stanford.EDU!REM@IMSSS>
<M> From: mcvax!pilatus!ceb@uunet.UU.NET
I nominate using BBN/UCI-lisp editor terminology here, namely "embed".
CONS and LIST are embedding functions.
. . .
terminology, namely "extract". CAR and NTH (in regard to its list
argument) are extracting functions.
(:- Or cut off their damn heels :-)
(N.B. That's from a comedy album played on KFAT dealing with chain saw.)
In this case of LetRec, have low-level mechanism (part of LetRec) pass a
dummy forwarding cell, evaluate normally, then after return more
low-level LetRec mechanism do the replacement for the true value to
create circularity. This localizes the implementation work to LetRec
itself, not random functions such as CONS, thus it can be done outside a
Scheme-style lazy-evaluator within a normal evaluator.
Now that you mention chain saws, it occurs to me that you really don't
have to declare a special class of functions at all. If what you
meant above was something like:
"Whenever a reference occurs to a structure chunk that
occurs elsewhare in the structure, you substitute in place a
forwarding cell, and then as you exit the letrec context, you
go through and replace al of these forwarding cells (which you have
kept around in a list) with their true references, then . . .
*Should you make a such a reference inside an non-embedding or
extracting function, then as your forwarding cell tries to
work its way through the offending procedural filter before
you exit, then you will get a "Warning: non-numeric argument
passed to (whatever)"."
(Its just like trying to pass something which won't cut through a
circular saw => it jams).
Otherwise, it seems you've got the idea well framed.
[But then again, all this is probably inside that 1980 ACM article
Steele mentioned as well; wheels tend to get reinvented.]
Ps. Glad to see KFAT back.
∂14-Apr-88 2016 Common-Lisp-mailer Reader references
Received: from space-tech.arpa by SAIL.Stanford.EDU with TCP; 14 Apr 88 20:15:59 PDT
Date: 14 Apr 88 22:12:00 CST
From: "Perry Alexander" <alexander@space-tech.arpa>
Subject: Reader references
To: "common-lisp" <common-lisp@sail.stanford.edu>
Reply-To: "Perry Alexander" <alexander@space-tech.arpa>
Does anyone out there know of any references having to do with the Lisp
reader and read macros? (Besides CLtL) We are beginning to write some very
complicated databases and realize that taking full advantage of read macros
will help performance. However, no one seems to deal with this in detail
besides in CLtL. Any pointers?
- Perry
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Perry Alexander ARPA : alexander@space-tech.arpa
The University of Kansas
Center for Research/TISL
2291 Irving Hill Dr.
Lawrence, KS. 66045
(913)-864-7753
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
------
∂14-Apr-88 2315 Common-Lisp-mailer &rest [discussion] replacement/addition
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 14 Apr 88 23:15:47 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac18084; 15 Apr 88 2:07 EDT
Received: from cs.umass.edu by RELAY.CS.NET id av18068; 15 Apr 88 1:59 EDT
Date: Thu, 14 Apr 88 12:07 EDT
From: ELIOT@cs.umass.edu
Subject: &rest [discussion] replacement/addition
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"pf@ti-csl.csc.ti.COM" "Paul Fuqua" 14-APR-1988 03:50
The general rule around here is, "Don't modify a list if you don't know
where it came from." Many constants in our implementation end up in
read-only areas, and there are other instances of sharing than APPLY/&REST,
so it's seen as a bad idea to use destructive operations on
random data objects.
Anyone who doesn't follow this rule is writing potentially buggy code.
One of the central points of the &rest discussion is the proposal to
stipulate, by definition, that &rest lists "come from" the function
which recieves them. The only ramification of this definition for
otherwise correct Common Lisp implementations is that APPLY/&rest lists
cannot be shared. So close, and yet so far. From your discussion
of the TI microcode, it sounds like the runtime penalty would be limited
to some extra stack allocation (NO real consing) except in cases
where the &rest list is actually saved. This is better than I had
expected was possible.
My measurements did not count functions with &key arguments. I believe
there are other possible ways to implement &key, so it would not
be fully fair to lump them with &rest. My measurement code was
included in my earlier message, and it can easily be modified to
measure &key (or &optional or &aux for that matter.)
Chris Eliot
∂21-Apr-88 1030 Common-Lisp-mailer Lisp & Functional Programming 88 (LONG)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 21 Apr 88 10:27:54 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA11273; Thu, 21 Apr 88 11:28:21 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA01376; Thu, 21 Apr 88 11:28:17 MDT
Date: Thu, 21 Apr 88 11:28:17 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8804211728.AA01376@cons.utah.edu>
To: common-lisp@sail.stanford.edu
Subject: Lisp & Functional Programming 88 (LONG)
What follows is the Advance Program for L&FP 88. There is no
electronic version of the registration form, so if you want a copy,
please send me your US Mail address, and I'll mail you a copy. If you
are a member of SIGPLAN, SIGART, or SIGACT, then you will be receiving
a copy in about 3 weeks.
Bob.
====================================================================
1988 Lisp and Functional Programming
Conference
Advance Program
Snowbird, Utah, July 25-27, 1988
A conference sponsored by the ACM Special Interest
Groups on Programming Languages, Artificial Intelligence,
and Computer Architecture.
Chairs and Committee Members
General Chair: Jerome Chailloux
INRIA
Domainede Voluceau-Rocquencourt
B.P. 105
Le Chesnay Cedex, France
chaillou@inria.inria.fr
Program Chair: Robert Cartwright, Rice University
Committee: Harold Abelson, MIT
Richard Bird, Oxford University
Luca Cardelli, DEC Systems Res. Ctr.
Robert Cartwright, Rice University
Richard Gabriel, Lucid Inc.
Christopher Haynes, Indiana University
Gerard Huet, INRIA Rocquencourt
Gilles Kahn, INRIA Sophia Antipolis
David Moon, Symbolics Inc.
Guy Steele, Thinking Machines Corp.
Carolyn Talcott, Stanford University
Local Robert Kessler
Arrangements: University of Utah
Department of Computer Science
Salt Lake City, Utah 84112
kessler@cs.utah.edu
(801) 581-5017
Treasurer: Shane Robison, Apple Computer
!
Sunday, July 24th
06:00-09:00 pm Reception
Monday, July 25th
08:00-08:30 Continental Breakfast
08:30-09:30 Tutorial: Abstraction in Numerical Methods
Gerald Jay Sussman and Matthew Halfant (MIT)
09:30-10:30 Session 1: Chaired by Harold Abelson (MIT)
"Expressing Mathematical Subroutines Constructively"
Gerald Roylance (MIT)
"Exact Real Computer Arithmetic with Continued Fractions"
Jean Vuillemin (INRIA Rocquencourt)
10:30-11:00 Break
11:00-12:00 Session 2: Chaired by Richard Gabriel (Lucid, Inc.)
"Parallel Execution of Sequential Scheme with ParaTran"
Pete Tinker, Morry Katz (Rockwell International Science Center)
"Buckwheat: Graph Reduction on a Shared-Memory Multiprocessor"
Benjamin Goldberg (New York University)
12:00-02:00 Lunch
02:00-03:30 Session 3: Chaired by Christopher Haynes (Indiana University)
"A MathematicalSemantics for Handling Full Functional Jumps"
Matthias Felleisen (Rice University)
Mitch Wand (Northeastern University)
Daniel Friedman, Bruce Duba (Indiana University)
"Continuations May Be Unreasonable"
Albert Meyer, Jon G. Riecke (MIT)
"Lambda-V-CS: An Extended Lambda Calculus for Scheme"
Matthias Felleisen (Rice University)
03:30-04:00 Break
04:30-05:30 Session 4: Chaired by Guy Steele (Thinking Machines Corp.)
"Syntactic Closures" Alan Bawden, Jonathan Rees (MIT)
"Concrete Syntax for Data Objects in Functional Languages"
Kent Peterson (Chalmers University)
!
"A Variable-Arity Procedural Interface"
R. Kent Dybvig, Robert Hieb (Indiana University)
08:00-09:45 pm Session 5: Chaired by David Moon (Symbolics Inc.)
"The Scheme86 Pro ject: A System for Interpreting Scheme"
Andrew Berlin, Henry Wu (MIT)
"Strategies forImplementing Continuations"
Will Clinger, Anne Hartheimer (Semantic Microsystems)
Eric Ost (Metaphor Corp.)
"An Implementation of Portable Standard LISP on the BBN Butterfly"
Mark Swanson, Robert Kessler, Gary Lindstrom (University of Utah)
"Preliminary Results with the Initial Implementation of Qlisp"
Ron Goldman, Richard Gabriel (Lucid, Inc.)
Tuesday, July 26th
08:00-08:30 Continental Breakfast
08:30-10:00 Session 6: Chaired by Robert Cartwright (Rice University)
"PartialPolymorphic Type Inference and Higher-Order
Unification" Frank Pfenning (Carnegie-Mellon University)
"Bounded Quantifiers Have Interval Models"
Simone Martini (Universitadi Pisa)
"Type Inferencein a Database Programming Language"
Atsushi Ohori, Peter Buneman (University of Pennsylvania)
10:30-11:00 Break
10:30-12:00 Session 7: Chaired by Luca Cardelli (DEC Systems Res. Ctr.)
"The Milner-Mycroft Calculus is Tractable"
Fritz Henglein (New York University)
"ML With Extended Pattern Matching and Subtypes"
Lalita Jategaonkar, John Mitchell (Stanford University)
"An Implementation of Standard ML Modules"
David MacQueen (AT&T Bell Laboratories)
12:00-02:00 Lunch
02:00-03:30 Session 8: Chaired by Jerome Chailloux (INRIA Rocquencort)
"Graphinators and the Duality of SIMD and MIMD"
Paul Hudak, Eric Mohr (Yale University)
!
"Faster Combinator Reduction Using Stock Hardware"
A.C. Norman (Cambridge University)
"The SpinelessG-Machine"
G. L. Burn (GEC Research Limited)
S. L. Peyton Jones (University College London)
J. D. Robson (GEC Research Limited)
03:30-04:00 Break
04:00-05:30 Session 9: Chaired by Richard Gabriel (Lucid, Inc.)
"A Simple and Efficient Implementation Approach for
Single Assignment Languages"
Kourosh Gharachorloo, Vivek Sarkar, John L. Hennessy (Stanford University)
"An Improved Replacement Strategy for Function Caching"
William Pugh (Cornell University)
"Object-oriented Programming in Scheme"
Norman Adams (Tektronix) Jonathan Rees (MIT)
06:30- Banquet
Wednesday, July 27th
08:00-08:30 Continental Breakfast
08:00-10:00 Session 10: Chaired by Gilles Kahn (INRIA Sophia Antipolis)
"Objects as Closures: Abstract Semantics of Object-oriented Languages"
Uday Reddy (University of Illinois at Urbana-Champaign)
"Types, Classes, Metatypes, Metatypes Classes: An
Open-ended Data Representation Model for EU_LISP"
Christian Queinnec (LITP, Universite Paris)
Pierre Cointe(Rank Xerox)
"The Common Lisp Ob ject System Metaobject Kernel: A Status Report"
Daniel G. Bobrow, Gregor Kiczales (Xerox Palo Alto Research Center)
10:00-10:30 Break
10:30-12:00 Session 11: Chaired by Carolyn Talcott (Stanford University)
"A Unified System of Parameterization for Programming Languages"
John Lamping (Stanford University)
"Intensions and Extensions in a Reflective Tower"
Olivier Danvy, Karoline Malmkjaer (University of Copenhagen)
"Reification without Evaluation"
Alan Bawden (MIT)
!
Conference Information
The 1988 ACM LISP and Functional Programming Conference will be held at the
Snowbird Ski and Summer Resort at Snowbird, Utah. Snowbird is a world
renowned resort in the mountains near Salt Lake City that offers outstanding
skiing in the winter and a variety of recreational activities including
hiking, climbing, swimming, and tennis in the summer. Summer temperatures
typically range between 60 F and 80 F in the day and 30 F to 50 F at night.
Sweaters are advisable for evening wear.
The meeting rooms, book exhibits, and guest rooms for the Conference will
all be housed in the Cliff Lodge, which features an eleven story glass atrium
with a cocktail lounge and restaurant overlooking the rugged Peruvian Gulch.
The Lodge includes four restaurants offering a wide variety of cuisines.
The entire Snowbird complex includes seventeen full-service restaurants,
lounges, and fast-food operations. You will also have access to the Cliff
Lodge Health and Beauty Spa, which offers an array of services ranging
from the unique (herbal wraps, parafango treatments) to the stimulating
(whirlpool, steamroom, saunas, roof-top heated swimming pool, aerobics
and weight training).
You can make room reservations with Snowbird's Central Reservations Office
by calling (800)453-3000 or (801)532-1700. Snowbird requires a deposit for
one night's lodging within ten days of booking. The deposit will be refunded
if the room is cancelled within 48 hours of arrival. If you book reservations
by June 24, 1988, you are entitled to the following special rates: $64 for a
single occupancy; $70 for a double occupancy; $104 for a deluxe bedroom,
single occupancy; and $110 for a deluxe bedroom, double occupancy. To receive
these special rates you must mention the ACM L&FP Conference when you place
your reservations. Each additional person will be charged $6 per day;
children under the age of 16 may stay for free in a room with a parent. These
rates are available from Saturday, July 23, 1988 through Friday, July 29,
1988, permitting conference attendees to extend their conference stay into
a short vacation. Some possible activities include rock climbing lessons,
backpacking trips, and helicopter tours.
Delta Airlines, which has a major hub in Salt Lake City, is offering
special round-trip fares to North American conferees of the 1988 ACM
Conference on Lisp and Functional Programming. First, Delta will allow an
additional 5% savings off published round-trip fares within the United States
and San Juan; and for passengers not qualifying for any published discounts,
Delta will allow the following two (seven-day advance purchase) discounts off
unrestricted round-trip coach fares: 40% from domestic cities and 35% from
Canadian cities. Delta also serves Europe and Japan.
To take advantage of these discounts, call (800) 345-1647 (within
Indiana (800) 822-4730; from Canada (812) 333-3360 collect) and ask
for Lana. The Internet address may be used for initial contact, as well
(acmtravel@iuvax.cs.indiana.edu); include daytime phone number and hours.
These fares are valid from July 23 to July 30, 1988.
Snowbird is located 31 miles or 40 minutes from the Salt Lake City
International Airport, and is easily accessible by taxi, car, bus (or
helicopter). Various transportation companies provide van and motorcoach
service to Snowbird. For four or more people, the current van cost is $10
per person. Limousine and car rental service is also available as well as
City Cab, Ute Cab and Yellow Cab (Cab fares should be about $42).
Conference activities will include a reception Sunday night and a
chairlift ride to an open meadow for a BBQ lunch on Monday. Tuesday's lunch
will includea tram ticket and a box lunch. You can ride Snowbird's 125
passenger aerial tram to the top of the 11,000 foot Hidden Peak, with its
spectacular view of the Wasatch Mountain Range and Salt Lake Valley.
You may either hike back down where you will have the opportunity of seeing
historic silver mine shafts from the 1800's, or you can make the return trip
by tram. That night will include the banquet dinner on the Pavilion.
Advance registration for the Conference is $225 for ACM and SIG members
(SIGPLAN, SIGART, or SIGACT), $250 for ACM or SIG members, or $290 for
non-members. Advance registration cutoff is June 24, 1988. After June 24,
fees are $275 for ACM and SIG, $300 for ACM or SIG, and $350 for non-members.
The registration fee includes a copy of the proceedings, the reception Sunday
evening, luncheons on Monday and Tuesday, refreshments during the breaks,
continental breakfast Monday through Wednesday, and the Tuesday night banquet.
Speakers and program/conference committee members should use the $225 rate.
Extra banquet tickets can be purchased for $40.
Student advance registration is $75 for the Conference (June 24
cutoff date), and $100 for late registration. The student registration fee
does not include the lunches or the banquet. On-site registration will be
accepted Sunday evening, and during the conference. We hope you will enjoy
your stay at Snowbird and we are looking forward to seeing you at the
Conference.
∂26-Apr-88 1619 Common-Lisp-mailer miscellaneous questions about declarations and type specfiers
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 26 Apr 88 16:19:36 PDT
Posted-Date: Tue, 26 Apr 88 13:27:25 PDT
Message-Id: <8804262027.AA08691@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA08691; Tue, 26 Apr 88 13:27:56 PDT
To: common-lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: miscellaneous questions about declarations and type specfiers
Date: Tue, 26 Apr 88 13:27:25 PDT
Sender: goldman@vaxa.isi.edu
1)is there any portable way to obtain the expansion of a type
specifier (FOO ...), given that FOO was defined by
(deftype FOO ...)
2) is there any portable way to ask if DEC is a legitimate declaration
specifier in an implementation (including the possibility that DEC
has been legitimized with
(PROCLAIM '(DECLARATION DEC))
3) is there any portable way to ask if a symbol or list S is a legitimate
type specifier in an implementation?
∂26-Apr-88 1840 Common-Lisp-mailer Re: miscellaneous questions about declarations and type specfiers
Received: from FRED.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 18:40:43 PDT
Received: from FRED.SLISP.CS.CMU.EDU by FRED.SLISP.CS.CMU.EDU; 26 Apr 88 21:41:49 EDT
To: goldman@vaxa.isi.edu
cc: common-lisp@sail.stanford.edu
Subject: Re: miscellaneous questions about declarations and type specfiers
In-reply-to: Your message of Tue, 26 Apr 88 13:27:25 -0700.
<8804262027.AA08691@vaxa.isi.edu>
Date: Tue, 26 Apr 88 21:41:32 EDT
From: Rob.MacLachlan@WB1.CS.CMU.EDU
To all three questions, the answer is no. Perhaps there should be. I
believe that proposals for TYPE-SPECIFIER-P have flown by in the past.
Rob
∂26-Apr-88 2114 Common-Lisp-mailer miscellaneous questions about declarations and type specfiers
Received: from labrea.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Apr 88 21:14:20 PDT
Received: by labrea.Stanford.EDU; Tue, 26 Apr 88 21:14:23 PDT
Received: from bhopal.lucid.com by edsel id AA12440g; Tue, 26 Apr 88 19:57:24 PDT
Received: by bhopal id AA03767g; Tue, 26 Apr 88 19:59:27 PDT
Date: Tue, 26 Apr 88 19:59:27 PDT
From: Jon L White <edsel!jonl@labrea.Stanford.EDU>
Message-Id: <8804270259.AA03767@bhopal.lucid.com>
To: goldman@vaxa.isi.edu
Cc: common-lisp@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: goldman@vaxa.isi.edu's message of Tue, 26 Apr 88 13:27:25 PDT <8804262027.AA08691@vaxa.isi.edu>
Subject: miscellaneous questions about declarations and type specfiers
re: 1)is there any portable way to obtain the expansion of a type
specifier (FOO ...), given that FOO was defined by
(deftype FOO ...)
I don't think so. Sounds reasonable enough though -- I'll put it on my
personal list of items which ought to be submitted to the X3J13 Cleanup
committee for consideration. [I already have 7 or 8 issues relating
to the type system]
2) is there any portable way to ask if DEC is a legitimate declaration
specifier in an implementation (including the possibility that DEC
has been legitimized with
(PROCLAIM '(DECLARATION DEC))
Again I don't think so. Maybe this ought to go in with a proposal for some
functions that will query the global database relevant to proclamations and
declarations (e.g., has a particular variable been proclaimed special? what
is the current global settings of the OPTIMIZE qualities? and so on.)
3) is there any portable way to ask if a symbol or list S is a legitimate
type specifier in an implementation?
Guy Steele circulated several pages of "Clarifications" in December 1985,
in which he proposed adding a function TYPE-SPECIFIER-P. I don't see it
on the current agenda of the X3J13 Cleanup committee; consequently it has
been on my personal list of items that ought to be submitted "soon"
-- JonL --
∂05-May-88 0713 Common-Lisp-mailer Constant Functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 5 May 88 07:13:11 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad29834; 5 May 88 9:38 EDT
Received: from cs.umass.edu by RELAY.CS.NET id at04994; 5 May 88 9:34 EDT
Date: Wed, 4 May 88 10:35 EDT
From: ELIOT@cs.umass.edu
Subject: Constant Functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
CLtL P.68:
"Defconstant ... does licence the compiler to buildassumptions about
the value into programs being compiled."
This mechanism has been in place for some time, and I imagine most
people agree that it is useful. I don't know of any equivalent
mechanism for declaring that the definition of a function will not
change. A good compiler could make use of this knowledge to do
some useful optimizations. For example, knowing that the definition
of SIN won't change, and looking to see that SIN is defined as a
mathematical function (this might be hard) implies that (sin pi) can
be compiled into a number. Similarly, the compiler could freely
eliminate code to check argument counts and types if the call is
correct at compile time, and the callee is guaranteed (by declaration)
not to change.
As a specific proposal I would add a weak version of the INLINE declaration.
INLINE already effectively gives the compiler a licence to assume that
a function definition will not change. However, it also gives the
compiler a licence to compile "bloated" code.
My proposal is to add to CLtL P.159 a new declaration for CONSTANT-FUNCTION.
The declaration (CONSTANT-FUNCTION foo) specifies that the compiler
may assume that the semantics of FOO are fixed. The actual effect
depends upon the definition of FOO, the call, and any DECLARE (OPTIMIZE ..)
that are in effect. With SPACE=0, SPEED=3 this should be equivalent to
an INLINE declaration.
As a special case (declare constant-function) in a DEFUN is equivalent
to both a proclaim and the defun.
In any case, an implementation is free to completely ignore this
declaration.
Chris Eliot
Student, Umass Amherst.
∂05-May-88 1740 Common-Lisp-mailer Industrial-strength Lisp?
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 5 May 88 17:39:54 PDT
Received: by labrea.stanford.edu; Thu, 5 May 88 17:39:28 PDT
Received: from bhopal.lucid.com by edsel id AA06119g; Thu, 5 May 88 17:27:51 PDT
Received: by bhopal id AA29328g; Thu, 5 May 88 17:30:29 PDT
Date: Thu, 5 May 88 17:30:29 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805060030.AA29328@bhopal.lucid.com>
To: common-lisp@sail.stanford.edu
Subject: Industrial-strength Lisp?
At the end of this message, I've reproduced a portion of an interchange
taking place on the mailing list scheme@mc.lcs.mit.edu. The topic is a
somewhat broad argument centered around clarity of some publicly-available
code, and in general I can't get exicted about such issues (one man's
clarity and elegance is another man's poison).
However, I find it verrry interesting that this publicly-available Scheme
implementation has grown in size to rival Common Lisp. At least some of
the original fathers of Scheme recognize that it is a dialect of Lisp
not all that different from Common Lisp; their attraction to it was that
it was succinctly defined, and not ossified by the needs of productization,
so it was a choice vehicle for programming language research (indeed, this
justification was part of Lisp's glory for over 20 years).
But I have often claimed that as soon as you develop a language system
(like Lisp, Prolog, or Smalltalk) to the point of really being "industrial
quality", it will have grown so cancerously as to have lost virtually all
its original pristine beauty (** but see footnote below). Conventional
languages like C/FORTRAN/ADA/PASCAL/MODULA don't seem to have this property
because, I think, there is generally an "off line" approach to programming
in them; in fact, the correlate of an "Industrial Strength" Common Lisp is
more likely C+Unix(tm) rather than just C alone. ZetaLisp exhibits this
operating-system character much more so than Common Lisp (one of whose
goals was to be a portable language).
-- JonL --
-------------------------------------------------------------------------------
Date: Wed, 4 May 88 11:12:23 MDT
From: shebs%defun@cs.utah.edu (Stanley T. Shebs)
To: cph@zurich.ai.mit.edu
Cc: scheme@mc.lcs.mit.edu
In-Reply-To: Chris Hanson's message of Wed, 4 May 88 03:47:10 edt <8805040747.AA21368@kleph>
Subject: Re: Extending the address space of MIT Cscheme (long reply)
. . .
There are probably others, I haven't looked at every single one of the
120+ files and 50K+ lines of the C code...
> * Have you seen a lisp of comparable (or greater) functionality
> that is significantly better in either respect? Please name it,
> and explain why.
In the absence of a manual describing the "functionality" of CScheme,
it's impossible to compare it on that basis. I hope there's lots of
functionality, CScheme is larger than commercial Common Lisps (which is
amusing considering how Schemers abuse Common Lisp for its "bloat").
Spice Lisp/CMU Common Lisp has its flaws, but it's better overall (for
one thing, it's smaller!). T/Orbit has better structure and style, but
its documentation is too scanty to recommend. I would say that PSL/PCLS
is cleaner, but I am biased!
. . .
-------------------------------------------------------------------------------
** [Footnote]: Smalltalk-80 *might* be excepted from this criticism even
though it is rather large (some folks are aghast at the complexity of
the initial class structure). The early "pristine" versions were
probably vintage circa 72, but the world at large only really saw
it after the publication of the Smalltalk books (vintage 80).
∂05-May-88 1916 Common-Lisp-mailer Constant Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 5 May 88 19:15:53 PDT
Received: by labrea.stanford.edu; Thu, 5 May 88 19:15:14 PDT
Received: from bhopal.lucid.com by edsel id AA06909g; Thu, 5 May 88 19:03:16 PDT
Received: by bhopal id AA29673g; Thu, 5 May 88 19:05:54 PDT
Date: Thu, 5 May 88 19:05:54 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805060205.AA29673@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Wed, 4 May 88 10:35 EDT <8805051650.AA04252@edsel.lucid.com>
Subject: Constant Functions
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"? What you are
looking for is a way to say that "constant folding" is ok; of course,
the function must be defined and usable in the compilation environment
for this to work. Generally speaking, "constant folding" is ok as long
as the function is side-effect free; so maybe that is the declaration
you want?
re: The declaration (CONSTANT-FUNCTION foo) . . . With SPACE=0, SPEED=3 this
should be equivalent to an INLINE declaration.
I don't think so, or at least not if what you primarily want is a way to
legitimze "constant folding". For example,
(defun run-around-and-double (x)
...lots of contorted code ...
... ultimately returning (* 2 x) ...
)
Then declaring this a constant-function should permit the compiler to convert
(run-around-and-double '6) into '12; but hopefully wouldn't cause in-lining
of (run-around-and-double x). I see 'inline' and 'constant-function' as
independent dimensions.
re: As a special case (declare constant-function) in a DEFUN is equivalent
to both a proclaim and the defun.
This is too special-casey. Any declare in a DEFUN (or any other place that
admits 'declare') should have only local, lexical scope; or at least, so I
think.
-- JonL --
∂06-May-88 1119 Common-Lisp-mailer constant-function
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 6 May 88 11:15:36 PDT
Received: from cvaxa.sussex.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa09773; 6 May 88 18:19 BST
Received: from csuna (csuna.ARPA) by cvaxa.sussex.ac.uk; Fri, 6 May 88 17:34:50 bst
From: John Williams <johnw%cvaxa.sussex.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Fri, 6 May 88 12:07:14 BST
Message-Id: <14798.8805061107@csuna.cvaxa.sussex.ac.uk>
To: common-lisp@sail.stanford.edu
Subject: constant-function
A CONSTANT-FUNCTION declaration might save an indirection on
function call. Also, it would enable the compiler to make use
of information about a function that it (the compiler) has
worked out for itself. For example, in my Common Lisp, more
efficient function calling code can be planted if the compiler
knows how many results a function will return. For many function
definitions, the compiler can deduce the number of results. But
without some kind of CONSTANT-FUNCTION declaration, this information
can not be acted upon.
john
∂06-May-88 1434 Common-Lisp-mailer Constant Functions
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 6 May 88 14:34:39 PDT
Received: from fafnir.think.com by Think.COM; Fri, 6 May 88 17:33:04 EDT
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by fafnir.think.com; Fri, 6 May 88 17:32:57 EDT
Date: Fri, 6 May 88 17:34 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Constant Functions
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8805060205.AA29673@bhopal.lucid.com>
Message-Id: <19880506213427.6.BARMAR@OCCAM.THINK.COM>
Date: Thu, 5 May 88 19:05:54 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"? What you are
looking for is a way to say that "constant folding" is ok; of course,
the function must be defined and usable in the compilation environment
for this to work. Generally speaking, "constant folding" is ok as long
as the function is side-effect free; so maybe that is the declaration
you want?
This isn't how I interpreted Eliot's CONSTANT-FUNCTION request. In
Multics PL/I, we called the above "reducible". If the compiler knows
that a function is reducible, then it can use common subexpression
elimination to optimize multiple calls, e.g. (+ (red-fun 10) (red-fun
10)) could be optimized to (* (red-fun 10) 2).
But that's not what Eliot was talking about. His CONSTANT-FUNCTION
declaration promises that a function is not going to be redefined, so
the compiler may build in assumptions about things like the calling
sequence, the location of the code, etc.
It is the case that if the compiler does flow analysis and can determine
that a function is reducible on its own (for example, if a function
references no free variables and only calls reducible functions, it is
also reducible), then a CONSTANT-FUNCTION declaration would also allow
the compiler to make optimizations based on the reducibility. If the
function happens to be reducible, but not declared CONSTANT-FUNCTION,
the compiler can't make the optimization because the function might be
redefined to a non-reducible function.
re: The declaration (CONSTANT-FUNCTION foo) . . . With SPACE=0, SPEED=3 this
should be equivalent to an INLINE declaration.
I think "should" should be "could". CL doesn't yet specify the precise
meaning of the various optimization levels, so it would be up to an
implementor to decide that this combination means that it should
inline-code all constant functions.
I don't think so, or at least not if what you primarily want is a way to
legitimze "constant folding". For example,
(defun run-around-and-double (x)
...lots of contorted code ...
... ultimately returning (* 2 x) ...
)
Then declaring this a constant-function should permit the compiler to convert
(run-around-and-double '6) into '12; but hopefully wouldn't cause in-lining
of (run-around-and-double x). I see 'inline' and 'constant-function' as
independent dimensions.
I agree with Eliot's original statement. However, your version follows
as a natural occurrence. If the compiler is smart enough to determine
that RUN-AROUND-AND-DOUBLE does nothing but return its argument doubled,
then it should be able to determine this about the inline-substituted
code, too.
re: As a special case (declare constant-function) in a DEFUN is equivalent
to both a proclaim and the defun.
This is too special-casey. Any declare in a DEFUN (or any other place that
admits 'declare') should have only local, lexical scope; or at least, so I
think.
That's already not true of the VALUES declaration. It specifies an
attribute of the function being defined, just as Eliot was suggesting
above.
barmar
∂07-May-88 0456 Common-Lisp-mailer Constant Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 7 May 88 04:56:34 PDT
Received: by labrea.stanford.edu; Sat, 7 May 88 04:56:42 PDT
Received: from bhopal.lucid.com by edsel id AA13963g; Sat, 7 May 88 03:10:22 PDT
Received: by bhopal id AA05614g; Sat, 7 May 88 03:13:06 PDT
Date: Sat, 7 May 88 03:13:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805071013.AA05614@bhopal.lucid.com>
To: barmar@think.com
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Fri, 6 May 88 17:34 EDT <19880506213427.6.BARMAR@OCCAM.THINK.COM>
Subject: Constant Functions
I think you may have missed the thrust of my critique of Eliot's proposal.
It sarted out like this:
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"?
Basically, a compiler can't make *any* assumptions at all about a function
it is compiling a call to without assuming "constant-function" also. This
is as true of FTYPE and INLINE declarations as it would be for the more
limiting items you mention like number of required arguments, etc.
Similarly, an INLINE declaration must already imply "constant function";
but my critique claims that a general "constant function" declaration must
not by itself imply INLINE.
Of course, it should be ok to redefine a "constant function" providing the
particular assumptions made during compilation aren't changed. That leaves
very little you can do to a function that has been inline'd.
re: That's already not true of the VALUES declaration. It specifies an
attribute of the function being defined, just as Eliot was suggesting
above.
CLtL, p162 speaks of the VALUES declaration; it says nothing at all like
that. Would you like to try again to say what you meant? Remember also
that Eliot was suggesting that a such a declare be equivalent to a proclaim
(which modifies a global database) and that would give it indefinite scope;
but every other declare is lexically scoped.
-- JonL--
∂07-May-88 1000 Common-Lisp-mailer Constant Functions
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 7 May 88 09:59:56 PDT
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA08175@EDDIE.MIT.EDU>; Sat, 7 May 88 12:56:56 EDT
Received: by spt.entity.com (smail2.5); 7 May 88 12:41:12 EDT (Sat)
To: edsel!jonl@labrea.stanford.edu
Cc: barmar@think.com, ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Sat, 7 May 88 03:13:06 PDT <8805071013.AA05614@bhopal.lucid.com>
Subject: Constant Functions
Message-Id: <8805071241.AA26134@spt.entity.com>
Date: 7 May 88 12:41:12 EDT (Sat)
From: gz@spt.entity.com (Gail Zacharias)
I believe the point of a CONSTANT-FUNCTION declaration would be to allow
references to the function cell of a symbol to be replaced with its
compile-time contents (or moral equivalent thereof). I.e. to tell the
compiler that it can replace (FOO ...) with (FUNCALL '#<Function FOO> ...).
This is very different from declaring, say, that FOO returns a float. That
certainly doesn't give the compiler license to assume that I will never
redefine FOO, just that any definition I ever give it will be a
float-returning-function.
Regarding inlining, I think it is perfectly valid for a compiler to inline
explicit constant references to compiled functions (i.e. references of the
form '#<Function>) since there is nothing in common lisp that would allow you
to tell the difference. Allowing CONSTANT-FUNCTION's to get inlined under some
SPEED/SPACE settings would just be a special case of that.
Having said all that, I don't think a CONSTANT-FUNCTION declaration would be
very useful. Unlike variables, most functions in most programs are constant
(once debugging is done), and you don't really want to maintain huge sets of
CONSTANT-FUNCTION declarations all over the place (that you have to keep
turning off when you need to debug). I think it would be more useful to have
some syntax for requesting block compilation of a file or a set of files
(presumably with some argument to compile-file), and a way to declare
exceptions (for which purpose NOTINLINE declarations seem to be the defacto
standard). I don't really see any need here for language extensions, since
requesting block compilation is sort of an environmental issue that I don't
think needs to be standardized; and for the exceptions, NOTINLINE will do fine
since any implementation that 'snaps links' on functions declared NOTINLINE
is asking to lose anyway given current usage.
∂07-May-88 1059 Common-Lisp-mailer Re: Constant Functions
Received: from FRED.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 7 May 88 10:59:26 PDT
Received: from FRED.SLISP.CS.CMU.EDU by FRED.SLISP.CS.CMU.EDU; 7 May 88 14:00:27 EDT
To: gz@spt.entity.com (Gail Zacharias)
cc: edsel!jonl@labrea.stanford.edu, barmar@think.com, ELIOT@cs.umass.edu,
common-lisp@sail.stanford.edu
Subject: Re: Constant Functions
In-reply-to: Your message of Sat, 07 May 88 12:41:12 -0400.
<8805071241.AA26134@spt.entity.com>
Date: Sat, 07 May 88 13:59:52 EDT
From: Rob.MacLachlan@WB1.CS.CMU.EDU
I agree with your analysis of the meaning of a function constant
declaration, but not with your comments on the desirability of
standardizing something of the sort.
I agree that the most common way of using this sort of knowledge would be a
"block compliation" mode, but I think finer granularity of control is also
useful.
In my compiler cleanup proposal, I suggest an "integration level" that
ranges from 0 to 3 (like an optimization quality). Any value greater than
0 allows the compiler to assume the function is constant, but increasing
values suggest increased inclination toward inline expansion. There is
also a "default integration level", which can be set by a proclamation and
applies to subsequently compiled DEFUNs.
It is worth standardizing on something of the sort insofar as it helps in
the writing of portable programs. Programs the redefine functions at run
time may not run in implementations that assume functions are constant.
This means that Common Lisp programs may only work in "go slow" mode.
If I were designing a new Lisp dialect, I would definitely have the
function defining form implicitly declare the function variable constant.
It is probably too late to make anything this sensible be the default in
Common Lisp, but it could be added as an upward compatible extension.
The 99.99 percent of programs that don't redefine functions could then have:
(PROCLAIM '(DEFAULT-INTEGRATION-LEVEL 1))
added at the beginning of the file, and could run fast.
Rob
∂07-May-88 2109 Common-Lisp-mailer Constant Functions
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 7 May 88 21:09:08 PDT
Received: from fafnir.think.com by Think.COM; Sun, 8 May 88 00:07:13 EDT
Return-Path: <barmar@Think.COM>
Received: by fafnir.think.com; Sun, 8 May 88 00:07:09 EDT
Date: Sun, 8 May 88 00:07:09 EDT
From: Barry Margolin <barmar@Think.COM>
Message-Id: <8805080407.AA26147@fafnir.think.com>
To: edsel!jonl@labrea.stanford.edu
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Sat, 7 May 88 03:13:06 PDT <8805071013.AA05614@bhopal.lucid.com>
Subject: Constant Functions
Date: Sat, 7 May 88 03:13:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
I think you may have missed the thrust of my critique of Eliot's proposal.
It sarted out like this:
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"?
I didn't address that part of your message in my response because I
agreed with it. That didn't seem to be the main thrust of your
message, though; you then went on to describe in detail a particular
type of optimization that seemed to be what you thought he was
proposing.
Basically, a compiler can't make *any* assumptions at all about a function
it is compiling a call to without assuming "constant-function" also. This
is as true of FTYPE and INLINE declarations as it would be for the more
limiting items you mention like number of required arguments, etc.
This is not true. If there has been an FTYPE declaration, the
compiler may make assumptions about the types of arguments and values
of a function, but certainly not about the implementation.
Similarly, an INLINE declaration must already imply "constant function";
but my critique claims that a general "constant function" declaration must
not by itself imply INLINE.
He merely suggested that "constant function" + speed=3 + space=0 might
cause a compiler to open-code. Remember how he first introduced his
idea: he wanted a declaration that encompassed everything that INLINE
does, except that it wouldn't FORCE open-coding. However, a compiler
might decide to open-code based on other factors, such as optimization
levels.
Of course, it should be ok to redefine a "constant function" providing the
particular assumptions made during compilation aren't changed. That leaves
very little you can do to a function that has been inline'd.
Or to a function that has been declared CONSTANT-FUNCTION.
re: That's already not true of the VALUES declaration. It specifies an
attribute of the function being defined, just as Eliot was suggesting
above.
CLtL, p162 speaks of the VALUES declaration; it says nothing at all like
that. Would you like to try again to say what you meant? Remember also
that Eliot was suggesting that a such a declare be equivalent to a proclaim
(which modifies a global database) and that would give it indefinite scope;
but every other declare is lexically scoped.
Sorry, I was thinking of Symbolics's VALUES declaration. They allow:
(defun fun (arg)
(declare (values name1 name2))
...)
Symbolics has a large number of declarations that specify aspects of
the function being defined. However, I now realize that none of the
standard CL declarations behave like this.
barmar
∂09-May-88 0926 Common-Lisp-mailer Re: Constant Functions
Received: from ALDERAAN.SCRC.Symbolics.COM ([128.81.41.109]) by SAIL.Stanford.EDU with TCP; 9 May 88 09:26:11 PDT
Received: from WINTER.SCRC.Symbolics.COM by ALDERAAN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191680; Mon 9-May-88 10:51:48 EDT
Date: Mon, 9 May 88 10:51 EDT
From: Charles Hornig <Hornig@ALDERAAN.SCRC.Symbolics.COM>
Subject: Re: Constant Functions
To: Rob.MacLachlan@WB1.CS.CMU.EDU, Gail Zacharias <gz@spt.entity.com>
cc: edsel!jonl@labrea.stanford.edu, barmar@think.com, ELIOT@cs.umass.edu,
common-lisp@sail.stanford.edu
In-Reply-To: The message of 7 May 88 13:59 EDT from Rob.MacLachlan@WB1.CS.CMU.EDU
Message-ID: <19880509145146.1.HORNIG@WINTER.SCRC.Symbolics.COM>
The approach we have taken at Symbolics is that all function references
are assumed to be "constant" unless they are declared (or proclaimed) to
be NOTINLINE. The idea is that failing to indirect through the function
cell is a minor form of inlining. This has several advantages:
The "constant" case is by far the most common in normal code. Avoiding
a user declaration here is very important.
We use an existing declaration which already has the desired meaning.
Declaring a function NOTINLINE is the standard way to make it traceable
and (as we see it) replaceable.
The environment does not have to carry this too far. Our environment
supports redefinition at the user level (compiling a new definition
from the editor) even when it doesn't at the code level
(SETF (SYMBOL-FUNCTION ...) ...).
∂09-May-88 0926 Common-Lisp-mailer [not about] Constant Functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 09:26:06 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 400672; Mon 9-May-88 12:24:29 EDT
Date: Mon, 9 May 88 12:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: [not about] Constant Functions
To: Barry Margolin <barmar@Think.COM>, edsel!jonl@labrea.stanford.edu
cc: ELIOT@cs.umass.edu, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805080407.AA26147@fafnir.think.com>
Message-ID: <19880509162404.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Sun, 8 May 88 00:07:09 EDT
From: Barry Margolin <barmar@Think.COM>
Date: Sat, 7 May 88 03:13:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
CLtL, p162 speaks of the VALUES declaration; it says nothing at all like
that.
That's a type-specifier, not a declaration.
Sorry, I was thinking of Symbolics's VALUES declaration. They allow:
(defun fun (arg)
(declare (values name1 name2))
...)
Symbolics has a large number of declarations that specify aspects of
the function being defined. However, I now realize that none of the
standard CL declarations behave like this.
Note that it would be wrong to say that such declarations are not
lexically scoped. The declarations are attached to a particular binding
of the name "fun" to a function definition, and they have the same scope
as that binding. Another way of saying roughly the same thing is that
the definitions are attached to the function object, not to the function
name. This is a better way to think of it, since such declarations work
in LAMBDA expressions as well, which don't have names.
One could introduce a different word for this type of declaration,
instead of using DECLARE, but I think that would be more confusing than
enlightening.
∂09-May-88 1416 Common-Lisp-mailer [not about] Constant Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 9 May 88 14:16:18 PDT
Received: by labrea.stanford.edu; Mon, 9 May 88 14:16:25 PDT
Received: from bhopal.lucid.com by edsel id AA22951g; Mon, 9 May 88 13:14:41 PDT
Received: by bhopal id AA12364g; Mon, 9 May 88 13:17:35 PDT
Date: Mon, 9 May 88 13:17:35 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805092017.AA12364@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: barmar@think.com, ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Mon, 9 May 88 12:24 EDT <19880509162404.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: [not about] Constant Functions
re: Date: Sat, 7 May 88 03:13:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
CLtL, p162 speaks of the VALUES declaration; it says nothing at all
like that.
That's a type-specifier, not a declaration.
Extended the way implied by barmar, it's also a declaration; see CLtL p158.
Just for the record, when one can do (DECLARE (<foo> X Y Z)), one usually
speaks of this as the <foo> declaration, even when <foo> is basically a
type-specifier. The rationale is apparently that this form is an
abbreviation for (DECLARE (TYPE <foo> X Y Z)).
re: One could introduce a different word for this type of declaration,
instead of using DECLARE, but I think that would be more confusing than
enlightening.
DECLARE is good enough. I'm happy to see that Symbolics didn't perpetrate
the lossage implied in recent messages that such a declare would be
equivalent to a (non-lexical) PROCLAIM.
-- JonL --
∂09-May-88 1420 Common-Lisp-mailer Constant Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 9 May 88 14:20:09 PDT
Received: by labrea.stanford.edu; Mon, 9 May 88 14:20:14 PDT
Received: from bhopal.lucid.com by edsel id AA23164g; Mon, 9 May 88 13:57:53 PDT
Received: by bhopal id AA12572g; Mon, 9 May 88 14:00:48 PDT
Date: Mon, 9 May 88 14:00:48 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805092100.AA12572@bhopal.lucid.com>
To: barmar@think.com
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Sun, 8 May 88 00:07:09 EDT <8805080407.AA26147@fafnir.think.com>
Subject: Constant Functions
re: Basically, a compiler can't make *any* assumptions at all about a function
it is compiling a call to without assuming "constant-function" also. This
is as true of FTYPE and INLINE declarations as it would be for the more
limiting items you mention like number of required arguments, etc.
This is not true. If there has been an FTYPE declaration, the
compiler may make assumptions about the types of arguments and values
of a function, but certainly not about the implementation.
I fail to see your point, since the compiler will also have to assume that
the function won't be redefined incompatibly. I hate to keep harping on a
point, but the first two lines I sent out on this topic say just about
all there is to be said:
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"?
Comments by Zacharis and Hornig also confirm that CONSTANT-FUNCTION as a
declaration gives you nothing beyond what is already implicit in the
collection of INLINE, FTYPE etc.; and CONSTANT-FUNCTION by itself cannot
substitute for any one of them individually. I particularly like Hornig's
explanation that unless the user explicitly declares a name NOTINLINE,
the symbolics compiler will make whatever assumptions of constantness it
feels like. You may not even know which aspect is relevant.
-- JonL --
∂09-May-88 1827 Common-Lisp-mailer [not about] Constant Functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 9 May 88 18:27:42 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 401217; Mon 9-May-88 21:25:50 EDT
Date: Mon, 9 May 88 21:25 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: [not about] Constant Functions
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: barmar@think.com, ELIOT@cs.umass.edu, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805092017.AA12364@bhopal.lucid.com>
Message-ID: <19880510012540.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 9 May 88 13:17:35 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
re: Date: Sat, 7 May 88 03:13:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
CLtL, p162 speaks of the VALUES declaration; it says nothing at all
like that.
That's a type-specifier, not a declaration.
Extended the way implied by barmar, it's also a declaration; see CLtL p158.
Just for the record, when one can do (DECLARE (<foo> X Y Z)), one usually
speaks of this as the <foo> declaration, even when <foo> is basically a
type-specifier. The rationale is apparently that this form is an
abbreviation for (DECLARE (TYPE <foo> X Y Z)).
I should just not answer this, but read table 4-1 and then resend your message.
∂09-May-88 2216 Common-Lisp-mailer Constant-Function
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 9 May 88 22:16:20 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aj02908; 10 May 88 1:11 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bg03727; 10 May 88 1:06 EDT
Date: Sun, 8 May 88 12:51 EDT
From: ELIOT@cs.umass.edu
Subject: Constant-Function
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"edsel!jonl@labrea.stanford.EDU" "Jon L White" 6-MAY-1988
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"?
Yes, I think this is true.
What you are
looking for is a way to say that "constant folding" is ok; of course,
the function must be defined and usable in the compilation environment
for this to work. Generally speaking, "constant folding" is ok as long
as the function is side-effect free; so maybe that is the declaration
you want?
No. I think my proposal is more general than that. At any point when I am
writing a large program I know that 50-90% of the functions are "mature"
and very unlikely to be changed, except perhaps for optimizations. I want
a way to tell that to the compiler.
re: The declaration (CONSTANT-FUNCTION foo) . . . With SPACE=0, SPEED=3 this
should be equivalent to an INLINE declaration.
I don't think so, ...
This is based upon a strict reading of CLtL P.160 about Declare Optimize.
"The value 0 means that the quality is TOTALLY unimportant." I think a
common-sense clause might be added to this description. Clearly we don't
want compilers to use up exponentially large amounts of space when given
a (declare (optimize (space 0)))
I see 'inline' and 'constant-function' as independent dimensions.
I think there are some close connections. 'inline' implies 'constant-function'
and 'constant-function' allows (but doesn't require) 'inline' compilation.
Small 'constant-function's would likely be compiled 'inline'.
re: As a special case (declare constant-function) in a DEFUN is equivalent
to both a proclaim and the defun.
This is too special-casey. Any declare in a DEFUN (or any other place that
admits 'declare') should have only local, lexical scope; or at least, so I
think.
That is a reasonable interpretation of declare, but
I think there should be some way to closely associate global
declaration-type stuff with a function's definition. For example,
make-array, defstruct and (ZL) defflavor have syntactic places for
arbitrary declarations about the new entity. DEFUN does not
except, perhaps, using an embedded DECLARE. Of course, the world
will not come to an end because people have to use a separate
proclaim. I just think it would be nicer to put everything
about a function definition into a single form.
Another solution is to define a macro encapsulaing the DEFUN and
PROCLAIM. For example ZL defsubst could be implemented this way
quite trivially. I have a more radical (sounding) proposal that
builds on this. I don't have time to defend it, so I am hoping
that it will grow out of the discussion naturally. I also don't
have a good name for such a macro. 'Defconfun' is rather bletcherous.
'define' would do, but Sussman's students would start schemeing
against me.
∂09-May-88 2234 Common-Lisp-mailer [not about] Constant Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 9 May 88 22:32:56 PDT
Received: by labrea.stanford.edu; Mon, 9 May 88 22:33:04 PDT
Received: from bhopal.lucid.com by edsel id AA25236g; Mon, 9 May 88 22:22:41 PDT
Received: by bhopal id AA14330g; Mon, 9 May 88 22:25:38 PDT
Date: Mon, 9 May 88 22:25:38 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805100525.AA14330@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: barmar@think.com, ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Mon, 9 May 88 21:25 EDT <19880510012540.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: [not about] Constant Functions
re: Extended the way implied by barmar, it's also a declaration;
see CLtL p158.
I should just not answer this, but read table 4-1 and then resend your
message.
You did read the phrase of my message "Extended the way implied by barmar ..."
didn't you? And you did notice his confession that this extension isn't part
of Common Lisp?
-- JonL --
∂09-May-88 2316 Common-Lisp-mailer Features
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 9 May 88 23:16:09 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.54/1.14) with UUCP
id AA23108; Tue, 10 May 88 00:21:52 EDT
Received: by mcvax.cwi.nl; Tue, 10 May 88 04:42:15 +0200 (MET)
Received: from cl.cam.ac.uk by kestrel.Ukc.AC.UK via Janet (UKC CAMEL FTP)
id aa01520; 9 May 88 20:35 BST
Via: harlqn; 9 May 88 18:43 BST (UK.AC.Cam.Cl.gnnt)
Received: from jung.harlqn.uucp (jung) by harlqn.uucp; Mon, 9 May 88 15:46:18 BST
Received: by jung.harlqn.uucp (3.2/SMI-3.2)
id AA12859; Mon, 9 May 88 15:45:46 BST
Date: Mon, 9 May 88 15:45:46 BST
From: Andrew Watson <mcvax!harlqn.co.uk!andrew@uunet.UU.NET>
Message-Id: <8805091445.AA12859@jung.harlqn.uucp>
To: common-lisp@sail.stanford.edu
Subject: Features
Steele (p358) on the 'feature' in the #+ read-time conditionalization facility:
"The feature should be the printed representation of a symbol or list. If
feature is a symbol, then it is true if and only if it is a member of the
list that is the value of the global variable *features*."
And *features* (p448):
"The value of the variable *features* should be a list of symbols that name
'features' provided by the implementation."
It is unclear to me from this whether an implementation should compare the
features as the symbols themselves or as their printnames. Lucid does the
latter, which seems more reasonable given the potential for confusion involving
packages. They also put their features in the keyword package, which is good
defensive programming.
Though a small point, this is rather important for portable code. Comments
anyone?
Regards,
Andrew.
+-----------------------------------------------------------------------------+
| Andrew Watson, andrew@uk.co.harlqn |
| Harlequin Ltd, Tel: +44 223 872522 |
| Cambridge, UK Fax: +44 223 872519 |
+-----------------------------------------------------------------------------+
∂10-May-88 0054 Common-Lisp-mailer Features
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 10 May 88 00:54:25 PDT
Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Tue 10 May 88 02:53:29-CDT
Date: Tue, 10 May 88 02:53 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: Features
To: Andrew Watson <mcvax!harlqn.co.uk!andrew@uunet.UU.NET>
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8805091445.AA12859@jung.harlqn.uucp>
Message-ID: <880510025324.6.GUMBY@BRAHMA.ACA.MCC.COM>
Date: Mon, 9 May 88 15:45:46 BST
From: Andrew Watson <mcvax!harlqn.co.uk!andrew@uunet.UU.NET>
I'm answering these in the opposite order to that in which you asked them:
And *features* (p448):
"The value of the variable *features* should be a list of symbols that name
'features' provided by the implementation."
It'd be nice to mark feaures on this list with honest-to-god symbols, to
reduce name collision. On the other hand you want to be able to check
this list at runtime, (perhaps to see whether or not to load something)
as well as at compile-time. Presumably the relevent package won't be
available until the feature itself has been loaded. (i.e. if MACLISP
had had packages, it wouldn't have made sense to do
(COND ((NOT (STAUS FEATURE FORMAT:FORMAT)) (LOAD '(FORMAT))))
since the FORMAT package probably wouldn't yet have been loaded.)
So features are really strings in one namespace; since the Book says
they should be symbols there are really only four portable packages into
which one may safely intern them. You might as well use keyword; it's
the safest bet. One reason that forcing them to be symbols is not a bad
idea is that it encourages people to use names which are easy to type,
though this isn't really that important.
Steele (p358) on the 'feature' in the #+ read-time conditionalization facility:
"The feature should be the printed representation of a symbol or list. If
feature is a symbol, then it is true if and only if it is a member of the
list that is the value of the global variable *features*."
This is the other good reason to make them symbols; hopefully INTERN is
at least as fast as string-equal; plus you'll only have to do it once
per #-/+. Hence the reader macro can do
(MEMBER (INTERN (READ-SYMBOL BLAH) *THE-KEYWORD-PACKAGE*) *FEATURES*) rather than
(MEMBER ... :KEY #'STRING-EQUAL).
It is unclear to me from this whether an implementation should compare the
features as the symbols themselves or as their printnames.
So it seems best to assume (I assume that you're implementing this
feature for Harlequin) that *features* will contain only keywords and
that you can intern what follows #+/- in KEYWORD and search the list
with EQ.
Note that some lisps don't behave this way, so you'll have to defend
agains them. Reading a package qualifier and throwing it away would
probably be OK. I hope the CL cleanup committee takes care of this.
Now, what reader syntax should you use to access the *bugs* list?
∂10-May-88 1333 Common-Lisp-mailer [Reducible declaration? and] Constant-Function
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 10 May 88 13:33:38 PDT
Received: by labrea.stanford.edu; Tue, 10 May 88 13:33:47 PDT
Received: from bhopal.lucid.com by edsel id AA28279g; Tue, 10 May 88 13:26:26 PDT
Received: by bhopal id AA16644g; Tue, 10 May 88 13:29:25 PDT
Date: Tue, 10 May 88 13:29:25 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805102029.AA16644@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Sun, 8 May 88 12:51 EDT <8805100526.AA25256@edsel.lucid.com>
Subject: [Reducible declaration? and] Constant-Function
re: I think there should be some way to closely associate global
declaration-type stuff with a function's definition. . . . Of course,
the world will not come to an end because people have to use a separate
proclaim. I just think it would be nicer to put everything
about a function definition into a single form.
This is a very good point. Perhaps the bottleneck is that CL can't
agree to semantics for *any* declaration (except for SPECIAL); some
compiler's basically throw all declarations away (except for SPECIAL).
re: Another solution is to define a macro encapsulaing the DEFUN and
PROCLAIM. . . . I also don't have a good name for such a macro.
'Defconfun' is rather bletcherous. 'define' would do, but Sussman's
students would start schemeing against me.
Part of the problem I've been having with the "constant function" declaration
is it's vagueness. In your original message you characterized it as "won't
redefine the function at runtime"; but as subsequent dialogue shows, there is
very little feeling that that implies anything worthwhile beyond what the
existing declarations (like ftype, speed/safety etc) provide. "Never
redefine, at all, ever" is just too stringent to be useful.
Further, my assumption that "Never redefine" characterizes the meaning
you intended seems to have caused confusion, as evidenced by replies by
others; in particular, some (perhaps yourself?) are primarily concerned
with the stability of the argument spectrum, so that a compiler *might*
be licensed to use a different function-to-function protocol. Maybe I'm
confused here too, in which case I'll just drop this line of reasoning; but
isn't argument spectra information is already specifiable via the ftype
declaration?
I tried to suggest that maybe you wanted to cover the case that is currently
not covered by any CL declaration -- that of "constant folding" (barmar
called it "reducible"; but his example failed to fold the constant form --
it only coalesced common subexpressions). Such "constant folding" at compile
time is a critical component of Lucid's optimizing compiler; but the data-
base of what is "foldable" isn't user-accessible. There is currently no CL
declaration that covers this case. Accepting barmar's terminology, I see a
reasonable place for a REDUCIBLE declaration; would you?
-- JonL --
∂10-May-88 1408 Common-Lisp-mailer Features
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 10 May 88 14:08:45 PDT
Received: by labrea.stanford.edu; Tue, 10 May 88 14:08:55 PDT
Received: from bhopal.lucid.com by edsel id AA28337g; Tue, 10 May 88 13:59:43 PDT
Received: by bhopal id AA16844g; Tue, 10 May 88 14:02:42 PDT
Date: Tue, 10 May 88 14:02:42 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805102102.AA16844@bhopal.lucid.com>
To: mcvax!harlqn.co.uk!andrew@uunet.uu.net
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Andrew Watson's message of Mon, 9 May 88 15:45:46 BST <8805091445.AA12859@jung.harlqn.uucp>
Subject: Features
re: *features* . . . It is unclear to me from this whether an implementation
should compare the features as the symbols themselves or as their
printnames. Lucid does the latter, which seems more reasonable given
the potential for confusion involving packages. They also put their
features in the keyword package, which is good defensive programming.
Lucid Common Lisp uses MEMBER as the test of *features* entry; and for
symbols, this becomes an EQ check, rather than "same-printname-p"; it also
implements the x3j13 proposal described in the next paragraph.
X3J13 is considering a proposal to require the setting of *package* to be
the KEYWORD package during the scope of reading the forms under a #+ or a
#-. This will tend to give the appearance of "namestring" comparison rather
than EQ only because, for example, #+LUCID will be read in the feature as
:LUCID, and the search on *features* will be for that symbol. The X3J13
proposal would permit reading in feature names like #+MACSYMA:HYPERLINEAR,
in which case the member test would be with the symbol MACSYMA:HYPERLINEAR.
Since *features* is an ordinary special variable (no contradiction in terms,
I hope! I only mean to say that it is "bindable" and not restricted to being
a "global" parameter), then nothing prevents you from pushing all kinds of
garbage on it. Say, 3.14159. But no consensus exists yet as to how the
#+ and #- syntax might interface to non-symbol entries.
-- JonL --
∂10-May-88 1419 Common-Lisp-mailer Constant-Function
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 10 May 88 14:18:51 PDT
Received: from relay2.cs.net by RELAY.CS.NET id an15217; 10 May 88 17:15 EDT
Received: from cs.umass.edu by RELAY.CS.NET id ai02249; 10 May 88 16:51 EDT
Date: Tue, 10 May 88 15:44 EDT
From: ELIOT@cs.umass.edu
Subject: Constant-Function
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"edsel!jonl@labrea.stanford.EDU" "Jon L White" 10-MAY-1988
re: Basically, a compiler can't make *any* assumptions at all about a function
it is compiling a call to without assuming "constant-function" also. This
is as true of FTYPE and INLINE declarations as it would be for the more
limiting items you mention like number of required arguments, etc.
This is not true. If there has been an FTYPE declaration, the
compiler may make assumptions about the types of arguments and values
of a function, but certainly not about the implementation.
I fail to see your point, since the compiler will also have to assume that
the function won't be redefined incompatibly. I hate to keep harping on a
point, but the first two lines I sent out on this topic say just about
all there is to be said:
Isn't it the case that *any* proclaim about a function is equivalent to
saying that that aspect of the function is "constant"?
Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
(sqrt 5). You might redefine SQRT as SIN without violating the FTYPE.
Declaring SQRT a 'constant-function' does make this legitimate (as would
'inline'.) Thus FTYPE declarations absolutely *do not* imply
'Constant-Function' declarations.
Comments by Zacharis and Hornig also confirm that CONSTANT-FUNCTION as a
declaration gives you nothing beyond what is already implicit in the
collection of INLINE, FTYPE etc.; and CONSTANT-FUNCTION by itself cannot
substitute for any one of them individually. I particularly like Hornig's
explanation that unless the user explicitly declares a name NOTINLINE,
the symbolics compiler will make whatever assumptions of constantness it
feels like. You may not even know which aspect is relevant.
Some Symbolics users use ' in place of #' to get around this bug. (!)
I think it exists exactly because the 'constant-function' declaration
is missing, so there has not been a good global way to make it
happen legitimately. I certainly hope I never see a compiler that
feels it can open-code a random DEFUN without some sort of legitimizing
declaration. That's what zl:defsubst, 'inline' and 'constant-function' are
for.
'Inline' is a mistake. It specifies "that it is desirable for the
compiler to open-code calls to the specified functions" (CLtL 159).
This is a kludge. It expresses the fact that the functions are
'constant-functions' but then it goes too far and tries to tell the
compiler what to do with that knowledge. 'Constant-Function' is
clean. It says exactly what you mean, declaratively, without
trying to interfere with the compiler's decision about how to use
the information. The compiler is in a much better position to
decide whether it is "desirable" to open-code a function. It can
look at the speed/space optimization settings, the body of the function
and predicted code simplifications after the substitution.
'Constant-Function' should be thought of as a primitive for declaring
where the current boundary of a layered system lies. I might put
these forms into my INIT file:
(defun fix-base-system (pkg)
(do-all-external-symbols (sym pkg)
(when (fboundp sym)
(proclaim (list 'constant-function sym))))))
(fix-base-system 'lisp)
(fix-base-system 'kee)
(fix-base-system 'umass-utilities)
It doesn't make sense to do wholesale proclamations like this
using 'inline'. To me FORMAT is a 'constant-function' but it is
not "desirable for the compiler to open-code calls to" FORMAT.
Many other functions should be considered part of the fixed base
that I am building a system on, without being "desirable" subjects
for open-coding.
I think that a compiler should avoid doing anything that affects
tracability/redefinability until a function has been declared
a 'constant-function'. After that it may be desirable to declare
some 'constant functions' as 'inline' to encourage open-coding in
situations where the compiler's normal decision is wrong or not
trusted.
∂10-May-88 1926 Common-Lisp-mailer Constant-Function
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 10 May 88 19:25:26 PDT
Received: by labrea.stanford.edu; Tue, 10 May 88 19:25:33 PDT
Received: from bhopal.lucid.com by edsel id AA29717g; Tue, 10 May 88 19:17:10 PDT
Received: by bhopal id AA18005g; Tue, 10 May 88 19:20:10 PDT
Date: Tue, 10 May 88 19:20:10 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805110220.AA18005@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Tue, 10 May 88 15:44 EDT <8805102203.AA28707@edsel.lucid.com>
Subject: Constant-Function
re: Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
(sqrt 5). You might redefine SQRT as SIN without violating the FTYPE.
Right. So your intention for "constant function" really was more along the
line of "constant foldable" (or "reducible"), just as I guessed in my first
message?
In fact, "constant function" by this definition doesn't even imply a
constant argument sepectrum. Imagine a function (defun foo (x y) ...)
which is "folded" as follows: (foo 2 3) --> 5; then at runtime the user
redefines it as (defun foo (x y &optional z) ...) in such a way that
(foo 2 3) = (foo 2 3 nil) = 5. No violation of compiler optimizations.
re: Some Symbolics users use ' in place of #' to get around this bug. (!)
I think it exists exactly because the 'constant-function' declaration
is missing, . . .
Well, Hornig did mention, and others concurred, that the much more common
case is to want this assumption; and having to place extra declarations
around all the common cases would be a pain.
-- JonL --
∂11-May-88 0814 Common-Lisp-mailer Constant-Function
Received: from XX.LCS.MIT.EDU by SAIL.Stanford.EDU with TCP; 11 May 88 08:14:38 PDT
Date: Wed, 11 May 1988 11:11 EDT
Message-ID: <SOLEY.12397480002.BABYL@XX.LCS.MIT.EDU>
From: SOLEY@XX.LCS.MIT.EDU
To: Jon L White <edsel!jonl@LABREA.STANFORD.EDU>
Cc: common-lisp@SAIL.STANFORD.EDU, ELIOT@CS.UMASS.EDU
Subject: Constant-Function
In-reply-to: Msg of 10 May 1988 22:20-EDT from Jon L White <edsel!jonl at labrea.stanford.edu>
Date: Tuesday, 10 May 1988 22:20-EDT
From: Jon L White <edsel!jonl at labrea.stanford.edu>
To: ELIOT at cs.umass.edu
cc: common-lisp at sail.stanford.edu
Re: Constant-Function
re: Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
(sqrt 5). You might redefine SQRT as SIN without violating the FTYPE.
Right. So your intention for "constant function" really was more along the
line of "constant foldable" (or "reducible"), just as I guessed in my first
message?
I think there are *three* kinds of compiler optimizations we're
talking about, not the two that have been bandied about. Given the function
(defun bar (x) (+ x 1))
the form (foo (bar 7) (bar 7)) might be compiled in several ways:
* INLINE compilation would be (foo (+ 7 1) (+ 7 1)). Yes, a later
constant folding stage would do more. But *this* is what INLINE means.
* CONSTANT FOLDING, as JonL point out, would be (foo 8 8). Note that
in the general case this potentially requires executing random user
function definitions from within the compiler.
* But REDUCIBLE is what Barmar said; avoid re-executing the function
at run time if the arguments are the same (yes, this is the same as
common subexp elim). In other words, a source-to-source transform
might yield (let ((gensym (bar 7))) (foo gensym gensym)). Note that
this does *not* require executing user code. I'm sure that this is
what Multics PL/1 does (though my old 1976 Multics PL/I manual
doesn't mention it).
These transforms obviously have different effects on code size and
runtime behavior (particularly in a non-functional language).
I agree with the comment that we need to provide the compiler with
information about *the function* rather than how we think the compiler
should *treat* the function at compile time.
-- Richard Soley
∂12-May-88 0013 Common-Lisp-mailer Constant-Function
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 May 88 00:13:44 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aj06210; 12 May 88 3:04 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bk13734; 12 May 88 2:57 EDT
Date: Wed, 11 May 88 14:55 EDT
From: ELIOT@cs.umass.edu
Subject: Constant-Function
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: Gail Zacharias <gz@spt.entity.COM>
I believe the point of a CONSTANT-FUNCTION declaration would be to allow
references to the function cell of a symbol to be replaced with its
compile-time contents (or moral equivalent thereof). I.e. to tell the
compiler that it can replace (FOO ...) with (FUNCALL '#<Function FOO> ...).
Constant-Function allows much more general and useful optimizations than this.
Regarding inlining, I think it is perfectly valid for a compiler to inline
explicit constant references to compiled functions (i.e. references of the
form '#<Function>) since there is nothing in common lisp that would
allow you to tell the difference.
TRACE is a Common Lisp function that allows you to see the difference.
Having said all that, I don't think a CONSTANT-FUNCTION declaration would be
very useful. Unlike variables, most functions in most programs are constant
(once debugging is done), and you don't really want to maintain huge sets of
CONSTANT-FUNCTION declarations all over the place (that you have to keep
turning off when you need to debug).
How does the compiler know that debugging is done, without a constant-function
declaration? Should a compiler just *assume* that every function is
debugged? What good are debugging tools then?
.... I don't really see any need here for language extensions, since
requesting block compilation is sort of an environmental issue that I don't
think needs to be standardized; and for the exceptions, NOTINLINE will do fine
since any implementation that 'snaps links' on functions declared NOTINLINE
is asking to lose anyway given current usage.
I don't believe there is such a clear separation between language and
environment issues. Furthermore I don't believe that "environment
issues" should be rigidly excluded from a language. We don't want
to impose requirements on the environment that would make Lisp less
portable. Certainly block compilation could be addressed as an
environment issue. But your proposal actually makes it clear that
this cannot be completely handled as an environment issue. You
want to split things up so that requests for block compilation are
made through the environment, but exceptions to this are handled
within the language? Wouldn't it be better to do things one
way or the other, rather than both at once?
∂12-May-88 0037 Common-Lisp-mailer Constant-Function
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 May 88 00:37:15 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa06273; 12 May 88 3:12 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bu13734; 12 May 88 3:03 EDT
Date: Wed, 11 May 88 16:22 EDT
From: ELIOT@cs.umass.edu
Subject: Constant-Function
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"edsel!jonl@labrea.stanford.EDU" "Jon L White" 11-MAY-1988 00:58
re: I think there should be some way to closely associate global
declaration-type stuff with a function's definition. . . . Of course,
the world will not come to an end because people have to use a separate
proclaim. I just think it would be nicer to put everything
about a function definition into a single form.
This is a very good point. Perhaps the bottleneck is that CL can't
agree to semantics for *any* declaration (except for SPECIAL); some
compiler's basically throw all declarations away (except for SPECIAL).
re: Another solution is to define a macro encapsulaing the DEFUN and
PROCLAIM. . . . I also don't have a good name for such a macro.
'Defconfun' is rather bletcherous. 'define' would do, but Sussman's
students would start schemeing against me.
Part of the problem I've been having with the "constant function" declaration
is it's vagueness.
Its perfectly clear to me :-)
In your original message you characterized it as "won't
redefine the function at runtime";
Meaning that the definition available at compile time will be the same
as the definition in force when the function call is executed.
The principle, but not exhaustive, consequences of this are that
the compiler can depend upon the FTYPE being fixed, and it is
permitted (but not required or even requested) to open code
the function call.
but as subsequent dialogue shows, there is
very little feeling that that implies anything worthwhile beyond what the
existing declarations (like ftype, speed/safety etc) provide. "Never
redefine, at all, ever" is just too stringent to be useful.
It "is an error" to change the definition of a function that has
been declared to be a 'constant-function' unless you recompile/reload
all calls to that function that have been compiled while that declaration
was in force. At best you may not get the new behavior. At worst you
might execute code with sufficiently invalid assumptions that the lisp
will crash.
Further, my assumption that "Never redefine" characterizes the meaning
you intended seems to have caused confusion, as evidenced by replies by
others; in particular, some (perhaps yourself?) are primarily concerned
with the stability of the argument spectrum, so that a compiler *might*
be licensed to use a different function-to-function protocol. Maybe I'm
confused here too, in which case I'll just drop this line of reasoning; but
isn't argument spectra information is already specifiable via the ftype
declaration?
I tried to suggest that maybe you wanted to cover the case that is currently
not covered by any CL declaration -- that of "constant folding" (barmar
called it "reducible"; but his example failed to fold the constant form --
it only coalesced common subexpressions). Such "constant folding" at compile
time is a critical component of Lucid's optimizing compiler; but the data-
base of what is "foldable" isn't user-accessible. There is currently no CL
declaration that covers this case. Accepting barmar's terminology, I see a
reasonable place for a REDUCIBLE declaration; would you?
I think that INLINE combined with algebraic simplification is equivalent
to constant folding. What I object to is that 'inline' can cause bloating
if the simplifier isn't good enough. It really is the phrase "it is
desirable to open-code" that bothers. If that said "It is allowed to
open-code..." and "the compiler should make a reasonable heuristic
decision based upon the amount of object code that is likely to
be produced." I want to tell the compiler what is legal and have it
do the right thing. That isn't my reading of the current definition
of 'inline'.
Consider (again) this code:
(defun fix-base-system (pkg)
(do-all-external-symbols (sym pkg)
(when (fboundp sym)
(proclaim (list 'constant-function sym))))))
(fix-base-system 'lisp)
(fix-base-system 'kee)
(fix-base-system 'umass-utilities)
This tells the compiler that I am not going to redefine "CONS" and "CAR"
and "CDR" and the other 500 functions. The compiler can do constant
folding and open coding or whatever is valid and appropriate for
calls to those functions. But I want the compiler to assume that
my functions are full of bugs (too true, too often) and calls to
those functions should be tracable/redefineable/debugable.
Is there some combination of FTYPE/INLINE that provides a portable
substitute for the above? It must not cause code-bloating in any
legitimate interpretation of the Common Lisp standard, and should
not require typing 500 declarations. Furthermore, it should not
cause conflicts because of upwards compatible extensions to
Common Lisp functions (such as extra keyword args).
∂12-May-88 0038 Common-Lisp-mailer Constant-Function
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 May 88 00:37:44 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab06273; 12 May 88 3:12 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bv13734; 12 May 88 3:04 EDT
Date: Wed, 11 May 88 16:22 EDT
From: ELIOT@cs.umass.edu
Subject: Constant-Function
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"edsel!jonl@labrea.stanford.EDU" "Jon L White" 11-MAY-1988 05:47
re: Knowing the FTYPE of sqrt does not allow a compiler to substitute 2.23 for
(sqrt 5). You might redefine SQRT as SIN without violating the FTYPE.
Right. So your intention for "constant function" really was more along the
line of "constant foldable" (or "reducible"), just as I guessed in my first
message?
No. This is a special case of constant function. The general definition
of constant-function is that it promises never to (incompatibly) redefine
the function. Constant folding can occur by two processes.
(1) The compiler can open-code SQRT (above) or FOO (below) and
algebraically simplify the result. In this case we are assuming
the simplifying did very well and reduced the code to a constant.
(2) The compiler somehow knows that the function is reducible,
and proceeds to evaluate the form (in the compilation environment)
and substitute the result.
In fact, "constant function" by this definition doesn't even imply a
constant argument sepectrum. Imagine a function (defun foo (x y) ...)
which is "folded" as follows: (foo 2 3) --> 5; then at runtime the user
redefines it as (defun foo (x y &optional z) ...) in such a way that
(foo 2 3) = (foo 2 3 nil) = 5. No violation of compiler optimizations.
This doesn't make any sense to me. This redefinition "is an error" but
you will probably get away with it. The fact that in this one example
we have not depended upon the fixed FTYPE aspect of a 'constant-function'
does not make it legitimate to overgeneralize and assume that
in no example is the FTYPE crucial.
re: Some Symbolics users use ' in place of #' to get around this bug. (!)
I think it exists exactly because the 'constant-function' declaration
is missing, . . .
Well, Hornig did mention, and others concurred, that the much more common
case is to want this assumption; and having to place extra declarations
around all the common cases would be a pain.
In itself this isn't important, but it leads to the general question of
what constant-function is intended for. The relevant buzzwords
are "layered systems" and "block-compilation". Initially a
function definitoin must be considered somewhat tentative.
Perhaps the semantics aren't quite right. Perhaps there is a bug
in the definition. In any case it is important that redefinition
and tracing work correctly. Eventually this prototype phase ends,
and the function definition can be fixed with constant-function.
Subsequently the compiler can use knowledge about the arguments,
body and even compiled code for the constant-function. ("Snapping
uuolinks" as Maclisp called it is effectively an optimization at
the compiled code level.)
If you believe this model of software development then Hornig's point
is wrong. You do not need "extra declarations arount all the common cases"
because you (generally) use a single PROCLAIM for every function in
the base layer of your system. (Hence the motivation to associate
the declaration with the DEFUN.) Happily the Common Lisp declaration
system also provides fine-grained control of this form of block
compilation.
∂12-May-88 2147 Common-Lisp-mailer Constant-Function
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 12 May 88 21:46:57 PDT
Received: by labrea.stanford.edu; Thu, 12 May 88 21:33:54 PDT
Received: from bhopal.lucid.com by edsel id AA10381g; Thu, 12 May 88 21:33:37 PDT
Received: by bhopal id AA24689g; Thu, 12 May 88 21:36:45 PDT
Date: Thu, 12 May 88 21:36:45 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805130436.AA24689@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Wed, 11 May 88 16:22 EDT <8805120817.AA05875@edsel.lucid.com>
Subject: Constant-Function
re: Consider (again) this code:
. . .
(fix-base-system 'lisp)
(fix-base-system 'kee)
(fix-base-system 'umass-utilities)
This tells the compiler that I am not going to redefine "CONS" and "CAR"
and "CDR" and the other 500 functions. The compiler can do constant
folding and open coding or whatever is valid and appropriate for
calls to those functions. But I want the compiler to assume that
my functions are full of bugs (too true, too often) and calls to
those functions should be tracable/redefineable/debugable.
. . .
Is there some combination of FTYPE/INLINE that provides a portable
substitute for the above? ...
The very question as to whether such a declaration would be at all useful,
as well as the degree of its utility, depends on how an implementation does
function-to-function interfaces. Few people in the common lisp community
have been desirous of imposing particular Lisp-system implementation
techniques into the portable standard; thus it's not surprising that few
are interested in standardizing on implementation specific tricks.
On the other hand, what is useful about the "constant-foldable" declaration
is that the transformation (sqrt 2.0) ==> 1.414... is independent of how
any Lisp system (or compiler) is built [except to the degree that you view
this as a "compiler optimization".] User-level macros can do the same
thing, but probably less thoroughly than the compiler. It only depends
upon knowing some simple properties about the function SQRT.
Also, the type system in Common Lisp isn't purely a "compiler efficiency"
hack; although I'm not aware of a really good "type inferencing" CL
compiler, this declarational information can be used in the sense of
"strong typing". Thus its justification is not merely that fixnum
declarations can make compiled code run faster. [But I admit that there
are so many systems wanting at least some type declarations for efficiency
that a few lone "hold outs" against them probably couldn't prevent their
appearance in CL].
Perhaps "block compilation" is a better line of pursuit since it has some
implications for "modularity" as well as potential for code efficienty.
Note that lots of somewhat-incompatible redefinitions of functions don't
invalidate FTYPE, or INLINE, or "constant-foldable" assumptions; but they
would invalidate the definition you have given (again!) for "constant
function", i.e. that it merely means "I won't redefine this function at
runtime". [This is the point you said didn't make sense to you; I'm sorry
I don't know how to put it in any plainer words]. Thus even in an
implementation whose compiler could profit from such information, the
declaration seems like overkill because it is too easy to violate its
contract without violating any useful requirement. It needs to be more
specific (thus I would call it "vague" for not being that specific).
Note also that there is a proposal to the x3j13 "cleanup" committee to make
it an error to redefine any function named in the Lisp package; this would
cover your case (fix-base-system 'lisp). But the proposal is not particlarly
for the purpose of enabling potential compiler tricks; rather (I think) it
is for the purpose of facilitating reasonable standards for code sharing.
I.e., how can you absorb my portable code that uses lisp:append if you have
redefined it to do something totally different.
-- JonL --
∂12-May-88 2159 Common-Lisp-mailer Constant-Function, and integration-level
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 12 May 88 21:59:34 PDT
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA04276@EDDIE.MIT.EDU>; Fri, 13 May 88 00:59:13 EDT
Received: by spt.entity.com (smail2.5); 13 May 88 00:53:49 EDT (Fri)
To: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: ELIOT@cs.umass.edu's message of Wed, 11 May 88 14:55 EDT <8805120732.AA10050@EDDIE.MIT.EDU>
Subject: Constant-Function, and integration-level
Message-Id: <8805130053.AA14552@spt.entity.com>
Date: 13 May 88 00:53:49 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
Date: Wed, 11 May 88 14:55 EDT
From: ELIOT@cs.umass.edu
From: Gail Zacharias <gz@spt.entity.COM>
Regarding inlining, I think it is perfectly valid for a compiler to
inline explicit constant references to compiled functions (i.e.
references of the form '#<Function>) since there is nothing in common
lisp that would allow you to tell the difference.
TRACE is a Common Lisp function that allows you to see the difference.
No. Common Lisp doesn't provide a way to trace disembodied functions.
I don't really understand the rest of your message. The point I was trying to
make is that since most DEFUN'ed functions are constant, it's not very useful
to have to have a constant-function declaration for every DEFUN in your
program. Rather, that should be the default (i.e. implementations should be
allowed to assume it), so that correct portable programs *must* explicitly
mark the exceptions. NOTINLINE works fine for that purpose.
Regarding Rob MacLachlan's integration-level, I agree that the concept is
useful, but I disagree that it's something a program should be requesting for
itself - it's something a user is requesting for the program. Put another
way, the integration level should not be sitting inside the program sources,
but rather be an argument to compile-file (or defsystem or an option on the
compile menu, or however it is the user usually goes about requesting a
compilation in his system). Since a correct program should work the same
regardless of the integration level it was compiled with, and since the
tradeoffs will be different for different implementations, there is no useful
criterion that a portable program can use to select its 'preferred'
integration-level.
∂12-May-88 2220 Common-Lisp-mailer visible hash tables
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 12 May 88 22:19:53 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Fri 13 May 88 01:19:40-EDT
Date: Fri 13 May 88 01:19:39-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: visible hash tables
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <12397896527.20.TOURETZKY@C.CS.CMU.EDU>
It bothers me that hash tables cannot be made "visible" data structures, i.e.,
there is no pretty printer switch you can set to see what's inside them.
Compare this with:
Vectors: contents displayed in #() notation if *PRINT-ARRAY* is T.
Arrays: contents displayed in #nA() notation if *PRINT-ARRAY* is T.
Structures: normally displayed in #S notation. As previously discussed,
there should be a simple way to select #<> notation for structures, e.g.,
if a flag named *PRINT-STRUCTURE* is NIL.
In teaching beginning to intermediate level Lispers to use hash tables, I find
my job would be a lot easier if they could see inside the things, just as they
can see inside structures and vectors. So what about a convention for printing
hash tables? Here is a suggestion:
(setq a (make-hash-table)) ;make a hash table
(setf (gethash 'foo a) 37) ;put some stuff in it
(setf (gethash 'bar a) 42) ;put some more stuff in it
(setf *print-hash* t) ;turn on the magic printer flag
a ==> #65H(EQL (FOO . 37) (BAR . 42))
The basic notation is:
#nH(type (key1 . value1) (key2 . value2) ...)
where "n" is the size of the hash table and "type" is the type, such as
EQL. The ordering of the dotted pairs is arbitrary. Comments?
-- Dave
-------
∂13-May-88 0050 Common-Lisp-mailer visible hash tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 13 May 88 00:50:46 PDT
Received: by labrea.stanford.edu; Fri, 13 May 88 00:38:14 PDT
Received: from bhopal.lucid.com by edsel id AA11001g; Fri, 13 May 88 00:40:58 PDT
Received: by bhopal id AA25455g; Fri, 13 May 88 00:44:06 PDT
Date: Fri, 13 May 88 00:44:06 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805130744.AA25455@bhopal.lucid.com>
To: Dave.Touretzky@c.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Dave.Touretzky@C.CS.CMU.EDU's message of Fri 13 May 88 01:19:39-EDT <12397896527.20.TOURETZKY@C.CS.CMU.EDU>
Subject: visible hash tables
re: The basic notation is:
#nH(type (key1 . value1) (key2 . value2) ...)
where "n" is the size of the hash table and "type" is the type, such as
EQL. The ordering of the dotted pairs is arbitrary. Comments?
I like it. But where is the hash-table equivalent of *PRINT-ARRAY* and
*PRINT-STRUCTURE*?
-- JonL --
∂13-May-88 0051 Common-Lisp-mailer visible hash tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 13 May 88 00:51:01 PDT
Received: by labrea.stanford.edu; Fri, 13 May 88 00:38:32 PDT
Received: from bhopal.lucid.com by edsel id AA11011g; Fri, 13 May 88 00:41:53 PDT
Received: by bhopal id AA25462g; Fri, 13 May 88 00:45:03 PDT
Date: Fri, 13 May 88 00:45:03 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805130745.AA25462@bhopal.lucid.com>
To: Dave.Touretzky@c.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Dave.Touretzky@C.CS.CMU.EDU's message of Fri 13 May 88 01:19:39-EDT <12397896527.20.TOURETZKY@C.CS.CMU.EDU>
Subject: visible hash tables
re: The basic notation is:
#nH(type (key1 . value1) (key2 . value2) ...)
where "n" is the size of the hash table and "type" is the type, such as
EQL. The ordering of the dotted pairs is arbitrary. Comments?
I like it. So is *PRINT-HASH* the hash-table equivalent of *PRINT-ARRAY* and
*PRINT-STRUCTURE*?
-- JonL --
∂13-May-88 0218 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 13 May 88 02:18:05 PDT
Received: by labrea.stanford.edu; Fri, 13 May 88 02:05:37 PDT
Received: from bhopal.lucid.com by edsel id AA11285g; Fri, 13 May 88 01:53:22 PDT
Received: by bhopal id AA25592g; Fri, 13 May 88 01:56:30 PDT
Date: Fri, 13 May 88 01:56:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805130856.AA25592@bhopal.lucid.com>
To: common-lisp@sail.stanford.edu
Subject: SIDE-EFFECT-FREE/STATELESS Functions
The discussion on "constant functions" seems to me to have reached a
dead end. But one good thing to come from it is the discovery that
CL provides no declaration that enables "constant folding", a very
useful optimization in quite a number of compilers.
In a more general sense, a user would want to be able to tell the
compiler that a certain named function has no internal state and that:
(1) it has no side effects, and
(2) its value is completely determined by its arguments.
Thus RANDOM is not side-effect-free, since it updates *random-state*; and
while FIND-SYMBOL is side-effect-free, it is not stateless since it is
sensitive to the setting of the global variable *package* as well as to
the entries in the package database. AREF is both side-effect-free and
stateless.
A compiler can perform the following optimization on a stateless and
side-effect-free function:
(A) Calls with arguments that are compile-time constant may be "folded"
into the literal data object evaluable at compile time;
(B) Common subexpressions that are calls to such a function may be
"reduced" [in the sense described by barmar and Soley];
(C) A call to such a function, whose return value is not consumed by
subsequent program parts, can be eliminated [this is also true if
the function is merely side-effect-free];
(D) Calls to such a function might be commutable with other program
segments ["communting" arguments in function calls is an optimization
that some compilers will try to do], since the call itself to such a
function doesn't have interactions with other program parts.
Would it be desirable to have two new declarations: SIDE-EFFECT-FREE and
STATELESS? Is there already a terminology somewhere in use for these
properties?
Oddly enough, functions which return a feshly-allocated pointer to some
updatable storage are not stateless, even though they are side-effect-free
-- CONS, APPEND, and MAKE-ARRAY are examples -- because the value of this
kind of function is essentially an address; and that address is sensitive
to the internal pointer to the "free list". Consider the following:
(let ((l '(1 2)))
(setq a (copy-list l))
(setq b (copy-list l)))
If COPY-LIST were stateless, then a and b should be identical; but the
existence of RPLACA means they can't be identical in a fundamental sense.
Note that the critical argument in this paragraph depends on the word
"updatable". For example, * is a stateless function; and in
(let ((x (factorial 100))
(y (factorial 200)))
(setq a (* x y)) ;surely a bignum
(setq b (* x y))) ;surely another bignum, of same value
a and b will hold identical results. True, they will likely be
distinguishable by EQ, but there is _no_ update function such that an
update to a would not be seen as an update to b also. The EQL comparison
is the relevant one for "identicalness", rather than EQ, even though a and
b are both pointers to freshly-allocated storage.
Long ago, PDP10 Interlisp provided a primitive language function called SETN
that would do just this -- it would bash the bits of a stored number object
-- but happily CL has nothing like this; if it did, then generic
multiplication would not be a stateless function.
-- JonL --
∂13-May-88 0840 Common-Lisp-mailer visible hash tables
Received: from REAGAN.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 13 May 88 08:34:31 PDT
Received: from JACKIE.AI.MIT.EDU by REAGAN.AI.MIT.EDU via CHAOS with CHAOS-MAIL id 111814; Fri 13-May-88 11:34:02 EDT
Date: Fri, 13 May 88 09:14 EDT
From: Richard Mlynarik <MLY@AI.AI.MIT.EDU>
Subject: visible hash tables
To: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <12397896527.20.TOURETZKY@C.CS.CMU.EDU>
Message-ID: <19880513131438.3.MLY@JACKIE.AI.MIT.EDU>
I have always thought that an extension to the #S macro
is the correct way to do this sort of thing.
Might I instead suggest
#S(hash-table :test #'eq :initial-contents #)
Such an extension would also allow one to present *PRINT-ESCAPE*
pathnames along the lines of
#S(pathname "FOO.EDU:>File-Server>barfmail.lisp")
Similarly
#S(byte-specifier 69 259)
#S(random-state ...)
and so forth.
In CLOSsage, I guess the way to do this would be have the reader call
a generic function whose methods are defined on either a class instance
or, somewhat less flexibly, `on' the prototype instance of a class.
(defmethod construct-instance-from-cruft-read-by-\#S
((class (eql (find-class 'pathname)))
&rest initargs)
(apply (lambda (name)
(pathname name))
initargs))
(defmethod construct-instance-from-cruft-read-by-\#S
((class structure-class)
&rest initargs)
(apply (secret-internal-constructor class) initargs))
I believe that this sort of approach was implemented in NIL
at some stage. RMS' lisp machine code had a similar feature.
[Then again, one could always print
"#.(let ((table (make-hash-table :test #'eql)))
(dolist (x '((key1 . val1) ...))
(setf (gethash table (car x)) (cdr x)))))"
Yum!]
∂13-May-88 0841 Common-Lisp-mailer Re: SIDE-EFFECT-FREE/STATELESS Functions
Received: from paris.Berkeley.EDU ([128.32.150.46]) by SAIL.Stanford.EDU with TCP; 13 May 88 08:41:26 PDT
Received: by paris.Berkeley.EDU (5.57/1.25)
id AA28975; Fri, 13 May 88 08:38:34 PDT
From: larus%paris.Berkeley.EDU@ginger.Berkeley.EDU (James Larus)
Message-Id: <8805131538.AA28975@paris.Berkeley.EDU>
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: common-lisp@sail.stanford.edu
Subject: Re: SIDE-EFFECT-FREE/STATELESS Functions
In-Reply-To: Your message of Fri, 13 May 88 01:56:30 PDT.
<8805130856.AA25592@bhopal.lucid.com>
Reply-To: larus@ginger.Berkeley.EDU
Date: Fri, 13 May 88 08:38:29 PDT
Dave Gifford and his graduate students at MIT have been working on
"effects" systems for language that parallel type systems, but
describe the effect of functions on the state of objects. Their ideas
can probably clarify the debate and help make the side-effect-free
declarations less ad-hoc. There are two Tech Reports and a few papers
that I am aware of:
@TECHREPORT{gifford:fx87,
AUTHOR = "David K. Gifford and Pierre Jouvelot and John M. Lucassen and
Mark A. Sheldon",
TITLE = "{FX-87} Reference Manual",
INSTITUTION = MITLCS,
YEAR = 1987,
NUMBER = "MIT/LCS/TR-407",
MONTH = Sep}
@TECHREPORT{lucassen:types,
AUTHOR = "John M. Lucassen",
TITLE = "Types and Effects: Towards the Integration of Functional
and Imperative Programming",
INSTITUTION = MITLCS,
YEAR = 1987,
NUMBER = "MIT/LCS/TR-408",
MONTH = Aug}
@INPROCEEDINGS{gifford:integrating,
AUTHOR = "David K. Gifford and John M. Lucassen",
TITLE = "Integrating Functional and Imperative Programming",
PAGES = "28-38",
BOOKTITLE = LISPC86,
YEAR = 1986,
MONTH = Aug}
@INPROCEEDINGS{lucassen:polymorphic,
AUTHOR = "John M. Lucassen and David K. Gifford",
TITLE = "Polymorphic Effect Systems",
BOOKTITLE = POPL15,
YEAR = 1988,
PAGES = "47-57",
ADDRESS = "San Diego, California",
MONTH = Jan}
/Jim
∂13-May-88 0932 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 May 88 09:32:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 404140; Fri 13-May-88 12:30:52 EDT
Date: Fri, 13 May 88 12:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805130856.AA25592@bhopal.lucid.com>
Message-ID: <19880513163043.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Here is the declaration that Symbolics currently uses (and has used for
some years) to provide this information to the compiler. We keep it
rather simple and do not try to break down side-effects into disjoint
categories; in other words, we assume that any location can be aliased
with any other location. This message does not constitute any kind of
commitment not to change the way this is done in the future.
The LT:SIDE-EFFECTS and LT:REPLICABILITY declarations license the
compiler to assume that the current definition and all future
redefinitions of the declared function will have the declared
properties. The reason these declarations exist is solely for that
constraint on future redefinitions, since this is information that the
compiler could easily deduce for itself by analyzing the function body.
These declarations are placed in the body of a function and
declare properties of the function being defined; these properties are
available in all scopes where the name of the function is lexically
available.
(DECLARE LT:(SIDE-EFFECTS SIMPLE)) means the function neither causes nor
is affected by side-effects. There aren't many examples of this (usually
one uses SIMPLE REDUCIBLE, see below); in Symbolics Common Lisp, CHAR-CODE
is an example, because the only side-effect that affects its value is
rebooting the machine (codes are assigned dynamically but once assigned
do not change for the duration of a session).
(DECLARE LT:(SIDE-EFFECTS READER)) means the function is affected by
side-effects but does not cause them. CONS is an example (allocation of
storage is not considered a side-effect because it doesn't affect the
result of any other function other than performance metering functions.)
(DECLARE LT:(SIDE-EFFECTS WRITER)) means the function may cause
side-effects and may be affected by them. This is the default.
(DECLARE LT:(SIDE-EFFECTS REDUCIBLE)) means the function is affected by
side-effects but does not cause them, and furthermore that the function
is subject to constant-folding. CAR is an example.
(DECLARE LT:(SIDE-EFFECTS SIMPLE REDUCIBLE)) means the function neither
causes nor is affected by side-effects, and furthermore that the
function is subject to constant-folding. + is an example.
LT:REPLICABILITY is much more implementation dependent but I'll
mention it here for completeness.
(DECLARE LT:(REPLICABILITY MANY-TIMES)) means it's worth computing
the function any number of times rather than binding a variable to it.
(DECLARE LT:(REPLICABILITY TWO-TIMES)) means it's worth computing
the function twice rather than binding a variable to it, but if a
common sub-expression calling this function occurs more than twice,
it should be bound to a variable.
∂13-May-88 0933 Common-Lisp-mailer visible hash tables
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 May 88 09:33:21 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 404144; Fri 13-May-88 12:33:13 EDT
Date: Fri, 13 May 88 12:33 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: visible hash tables
To: Dave.Touretzky@C.CS.CMU.EDU
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <12397896527.20.TOURETZKY@C.CS.CMU.EDU>
Message-ID: <19880513163315.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri 13 May 88 01:19:39-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
In teaching beginning to intermediate level Lispers to use hash tables, I find
my job would be a lot easier if they could see inside the things, just as they
can see inside structures and vectors. So what about a convention for printing
hash tables?
I'd be interested to hear why DESCRIBE isn't good enough for this.
∂13-May-88 1125 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 13 May 88 11:25:19 PDT
Return-Path: <barmar@Think.COM>
Received: from kulla.think.com by Think.COM; Fri, 13 May 88 14:23:13 EDT
Received: by kulla.think.com; Fri, 13 May 88 14:23:09 EDT
Date: Fri, 13 May 88 14:23:09 EDT
From: barmar@Think.COM
Message-Id: <8805131823.AA00371@kulla.think.com>
To: edsel!jonl@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Fri, 13 May 88 01:56:30 PDT <8805130856.AA25592@bhopal.lucid.com>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
Date: Fri, 13 May 88 01:56:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
In a more general sense, a user would want to be able to tell the
compiler that a certain named function has no internal state and that:
(1) it has no side effects, and
(2) its value is completely determined by its arguments.
Thus RANDOM is not side-effect-free, since it updates *random-state*; and
while FIND-SYMBOL is side-effect-free, it is not stateless since it is
sensitive to the setting of the global variable *package* as well as to
the entries in the package database. AREF is both side-effect-free and
stateless.
Be careful here. Lisp has various ideas of equality, so whether a
"value is completely determined by its arguments" has to be qualified
by the type of equality you are talking about. For example
(eq (aref some-array 3)
(progn (some-function some-array)
(aref some-array 3)))
is NOT guaranteed to return T, even though AREF is being given EQL
arguments in both cases.
I think you partially addressed this in the later portion of your
message, but I was uncomfortable with this AREF example you gave.
barmar
∂13-May-88 1238 Common-Lisp-mailer Re: Constant-Function, and integration-level
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 13 May 88 12:38:22 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by ACORN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 39735; Fri 13-May-88 15:32:58 EDT
Date: Fri, 13 May 88 15:33 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: Constant-Function, and integration-level
To: Gail Zacharias <gz@spt.entity.com>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805130053.AA14552@spt.entity.com>
Message-ID: <19880513193300.4.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: 13 May 88 00:53:49 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
I don't really understand the rest of your message. The point I was trying to
make is that since most DEFUN'ed functions are constant, it's not very useful
to have to have a constant-function declaration for every DEFUN in your
program. Rather, that should be the default (i.e. implementations should be
allowed to assume it), so that correct portable programs *must* explicitly
mark the exceptions. NOTINLINE works fine for that purpose.
I disagree entirely, that INLINE should be the default.
Consider:
o If I change a function, then I must recompile all functions
that call it, and hence all functions that call *them*, on
into the night, on the off chance the compiler may have open
coded it.
o Debugging becomes harder. One no longer has a function
invocation to use as a handle for, say TRACE. STEP doesn't
work as expected either, particularly if the compiler is
allowed to constant fold whenever it wants to.
I'm not arguing that this facility doesn't have it's place, I
just don't think it should be the default action. Most of us
are more concerned with maintainability than raw speed.
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂13-May-88 1248 Common-Lisp-mailer Re: Constant-Function
Received: from PECAN.CS.ROCHESTER.EDU ([192.5.53.206]) by SAIL.Stanford.EDU with TCP; 13 May 88 12:48:45 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by PECAN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 2708; Fri 13-May-88 15:42:17 EDT
Date: Fri, 13 May 88 15:42 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: Constant-Function
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8805130436.AA24689@bhopal.lucid.com>
Message-ID: <19880513194208.5.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: Thu, 12 May 88 21:36:45 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
The very question as to whether such a declaration would be at all useful,
as well as the degree of its utility, depends on how an implementation does
function-to-function interfaces. Few people in the common lisp community
have been desirous of imposing particular Lisp-system implementation
techniques into the portable standard; thus it's not surprising that few
are interested in standardizing on implementation specific tricks.
[...]
Perhaps "block compilation" is a better line of pursuit since it has some
implications for "modularity" as well as potential for code efficienty.
I am getting the sneaking suspicion that what these various
proposals boil down to is the desire for super-compilation, a
subject that has been much on my mind lately.
A simple example would be:
(defun foo (bar)
(mapcar #'bletch bar))
where we know that bletch is purely functional, that is, it's
output is soley determined by it's arguments, and has no
internal state.
We could then compile (third (foo mumble)) into (bletch (third
mumble)) which simply takes advantage of our "understanding"
of properties of foo and bletch.
This sort of thing seems to be an active research topic, and I
don't think it should have a bearing on a CL standard at this
time.
For a reference: see "The Concept of a Supercompiler",
Turchin, Valentin F. in ACM Transaciont on Programming
Languages and Systems, July 1986, V8 N3.
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂13-May-88 1453 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 13 May 88 14:52:59 PDT
Received: by labrea.stanford.edu; Fri, 13 May 88 14:52:30 PDT
Received: from bhopal.lucid.com by edsel id AA13315g; Fri, 13 May 88 14:43:42 PDT
Received: by bhopal id AA28645g; Fri, 13 May 88 14:46:52 PDT
Date: Fri, 13 May 88 14:46:52 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805132146.AA28645@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 13 May 88 12:30 EDT <19880513163043.4.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
Could you clarify how you are using "function" below? sometimes it seems
to apply to the symbol naming the routine being defined, and other times
it applies only to the compiled function object:
Date: Fri, 13 May 88 12:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
In-Reply-To: <8805130856.AA25592@bhopal.lucid.com>
The LT:SIDE-EFFECTS and LT:REPLICABILITY declarations license the
compiler to assume that the current definition and all future
redefinitions of the declared function will have the declared
properties. The reason these declarations exist is solely for that
constraint on future redefinitions, since this is information that the
compiler could easily deduce for itself by analyzing the function body.
These declarations are placed in the body of a function and
declare properties of the function being defined; these properties are
available in all scopes where the name of the function is lexically
available.
"Future redefinitions" must mean "future rebindings of some symbol-function
cell", right? Also, it appears as though the declaration can only
appear in the body of the code to which it applies; thus you couldn't
tell the compiler that BAR is reducible in the following way?
(defun foo (x)
(declare (<simple-or-whatever> bar))
(prog (...)
A (bar x) ;compiler might flush this call
(when (< (random 5) 3)
(return (bar 10))))) ;compiler could constant-fold this one
As I read your message, the only way the Symbolics compiler could obtain
information about 'bar', for use while compileing 'foo', is if 'foo' and
'bar' are being defined in the same lexical scope and the declare is
inside the definition of 'bar'. If this isn't right, then maybe you
could give some examples.
-- JonL --
∂13-May-88 1533 Common-Lisp-mailer Constant-Function, and integration-level
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 13 May 88 15:33:18 PDT
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA24460@EDDIE.MIT.EDU>; Fri, 13 May 88 18:32:26 EDT
Received: by spt.entity.com (smail2.5); 13 May 88 18:05:52 EDT (Fri)
To: miller@cs.rochester.edu
Cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: Brad Miller's message of Fri, 13 May 88 15:33 EDT <19880513193300.4.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Subject: Constant-Function, and integration-level
Message-Id: <8805131805.AA17354@spt.entity.com>
Date: 13 May 88 18:05:52 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
Clearly any decent development environment should not 'lock in' functions
during development. But that's not a question that a language standard need
address, it's something between you and your Lisp vendor...
The language issue is, when you've finished developing your program, using
whatever tools your implementation provides for that purpose, what properties
must that program have in order to be a correct Common Lisp program and hence
work in any other correct Common Lisp implementation. In this particular case,
the question is, can your program assume that redefining a DEFUN'ed function at
runtime will affect all calls to that function:
(1) Yes, unless it's been declared CONSTANT-FUNCTION
or (2) No, unless it's been declared NOTINLINE
I'm arguing that (2) is more useful. With (1), all portable programs which
wish to take advantage of implementations which might do significant
optimizations on constant functions would have to be accompanied by huge
sets of constant-function proclamations (yes, i know this can be a program
that you have to run before compiling, which maps through all symbols. It's
still awkward).
∂13-May-88 1801 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 May 88 18:01:17 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 404503; Fri 13-May-88 21:00:12 EDT
Date: Fri, 13 May 88 21:00 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805132146.AA28645@bhopal.lucid.com>
Message-ID: <19880514010013.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 13 May 88 14:46:52 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Could you clarify how you are using "function" below? sometimes it seems
to apply to the symbol naming the routine being defined, and other times
it applies only to the compiled function object:
It refers to the function object in all cases. I omitted the word
"name" in one place, and I've added it in brackets below.
Date: Fri, 13 May 88 12:30 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
The LT:SIDE-EFFECTS and LT:REPLICABILITY declarations license the
compiler to assume that the current definition and all future
redefinitions of the declared function [name] will have the declared
properties. The reason these declarations exist is solely for that
constraint on future redefinitions, since this is information that the
compiler could easily deduce for itself by analyzing the function body.
These declarations are placed in the body of a function and
declare properties of the function being defined; these properties are
available in all scopes where the name of the function is lexically
available.
"Future redefinitions" must mean "future rebindings of some symbol-function
cell", right?
I don't think I should admit to knowing what you mean by implementation
dependent concepts like "binding" and "cell". If the function was defined
by DEFUN, redefinition means evaluating a DEFUN for the same name.
Also, it appears as though the declaration can only
appear in the body of the code to which it applies; thus you couldn't
tell the compiler that BAR is reducible in the following way?
There was no function name field in the declaration syntax I showed.
The declarations apply to functions, not to function names, sorry about
the confusion. I don't know what it would mean to locally declare a
function to be free of side-effects; I think that's a property of the
function, not of a caller of the function.
(defun foo (x)
(declare (<simple-or-whatever> bar))
(prog (...)
A (bar x) ;compiler might flush this call
(when (< (random 5) 3)
(return (bar 10))))) ;compiler could constant-fold this one
As I read your message, the only way the Symbolics compiler could obtain
information about 'bar', for use while compileing 'foo', is if 'foo' and
'bar' are being defined in the same lexical scope and the declare is
inside the definition of 'bar'. If this isn't right, then maybe you
could give some examples.
I suspect I did not understand this comment. When defining a function
named bar, one declares properties of that function and all future
redefinitions of the function by putting a declare inside the function's
definition. When calling a function named bar, the declarations
attached to the definition that will be called are used.
∂13-May-88 2033 Common-Lisp-mailer replies to hash table comments
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 13 May 88 20:33:31 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Fri 13 May 88 23:33:21-EDT
Date: Fri 13 May 88 23:33:21-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: replies to hash table comments
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <12398139318.17.TOURETZKY@C.CS.CMU.EDU>
To JonL: Yes, *PRINT-HASH* would be a switch analogous to *PRINT-ARRAY*.
If T, then the contents of the hash table would be displayed. If NIL, then
the current #<HASH-TABLE ...> notation would be used. The initial value of
the switch would be implementation-dependent.
To Mlynarik: I'm not thrilled with the idea of generalizing #S to objects
other than defstructs, but I guess that's a matter of personal taste.
By the way, Symbolics writes pathnames as #P"/usr/dst/foo.bar".
To Moon: there are three reasons why DESCRIBE doesn't solve the problems
that arise in teaching beginners about hash tables:
1. In some implementations, DESCRIBE does not show the contents of a
hash table. CMU Common Lisp currently displays this regrettable (but
legal) behavior.
2. It is a hassle for a beginner to have to type (describe my-table)
every time he wants to see what's inside his hash table. And if
he's passing the hash table as an argument to a function, it would
be nice if its contents could be displayed automatically by TRACE
or by the debugger simply by setting *PRINT-HASH* to T. This kind
of behavior would make hash tables a first class "visible" data
structure, as easy to understand as lists and vectors.
3. The proposed #H notation would make it possible to read and write
hash tables from files, and to create them interactively with a single
expression rather than doing a MAKE-HASH-TABLE and a bunch of SETF's.
To recap, the proposal was that if *PRINT-HASH* was T, then hash tables would
be displayed as #nH(type (key1 . value1) (key2 . value2) ...) where "n" was
the size of the table and "type" was one of EQ, EQL, or EQUAL. When reading a
#H expression it should be possible to omit the numeric argument, in which case
the system will pick some reasonable size based on the number of key/value
pairs supplied. It should also be possible to omit the type, in which case EQL
is assumed.
So #H((FOO . 37) (BAR . 42)) might print as #20H(EQL (FOO . 37) (BAR . 42)).
-- Dave
-------
∂14-May-88 0015 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 14 May 88 00:14:59 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab08204; 14 May 88 1:50 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bt03216; 14 May 88 1:39 EDT
Date: Fri, 13 May 88 16:00 EDT
From: ELIOT@cs.umass.edu
Subject: SIDE-EFFECT-FREE/STATELESS Functions
To: Common-Lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"Common-Lisp@sail.stanford.edu"
From: IN%"edsel!jonl@labrea.stanford.EDU" "Jon L White" 13-MAY-1988 06:32
Subj: SIDE-EFFECT-FREE/STATELESS Functions
The discussion on "constant functions" seems to me to have reached a
dead end.
Agreed. But I do maintain that the 'inline' declaration would
be significantly more useful if the single word "desirable"
is changed to "allowable" in specifying its effect. This would
create a more appropriate division of responsibility between
the compiler and the programmer. No Common Lisp implementation
or program would have to be modified to implement this refinement
of the standard. In the future compilers would be encouraged
to make a reasonable context dependand decision about open coding.
Would it be desirable to have two new declarations: SIDE-EFFECT-FREE and
STATELESS?
I am in favor of such declarations. Presumably one would want a
compiler to try to verify these properties. Should "ERROR" and
"CERROR" be considered side effect free for this purpose?
If not then functions like division can't be considered side
effect free, since division by zero must signal an error.
Of course, if a compiler can check these properties it could
also compute them. But currently it would not be allowed
to use those computed properties.
∂16-May-88 1603 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 16 May 88 16:02:52 PDT
Received: by labrea.stanford.edu; Mon, 16 May 88 16:03:12 PDT
Received: from bhopal.lucid.com by edsel id AA26918g; Mon, 16 May 88 15:52:20 PDT
Received: by bhopal id AA02023g; Mon, 16 May 88 15:55:43 PDT
Date: Mon, 16 May 88 15:55:43 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805162255.AA02023@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 13 May 88 21:00 EDT <19880514010013.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
re: . . . When defining a function
named bar, one declares properties of that function and all future
redefinitions of the function [name] by putting a declare inside the
function's definition. When calling a function named bar, the
declarations attached to the definition that will be called are used.
(I inserted the bracketed "[name]" in your comments quoted above, to be
consistent with your emmendations of your previous message.)
The issue is that the Symbolics' declaration can't be a proclamation because
it doesn't apply specifically to a name for the function. It does seem a
bit of a departure from CLtL to acquire global compilation directions out
of the current binding of a function name rather than using PROCLAIM.
I see a reasonable amount of code that calls SETF on symbol-function; how
would the symbolics style declaration handle this? the same as if it had
been a DEFUN? Perhaps what is needed is something beyond DEFUN that, like
DEFVAR, will do implicit proclaims on the name as well as setting initial
values; (SETF SYMBOL-FUNCTION) would remain "primitive", like SETQ.
re: I don't think I should admit to knowing what you mean by implementation
dependent concepts like "binding" and "cell". . . .
The term "binding" to mean an assignment of value to an identifier, whether
temporary or permanent, has been around the Lisp world for decades. I don't
even think it is Lisp-world specific. Also, cells aren't especially
"implementation-dependent concepts" -- see the current discussion on the
Scheme mailing list about "CELLS" (especially re ML). Even beyond that
theoretical scope, there is a common practice in the Lisp comunity to speak
of setting a dynamic variable's value as "setting it's value cell"; rarely,
if ever, is there any point to making a distinction between the two,
regardless of how an implementation handles dynamic variables.
One interesting avenue for maintaining consistency between proclamations and
"reality" is to signal errors whenever the compiler can determine that a
proclamation is being violated. So an attempt to proclaim RANDOM "simple"
would generate an error; and a subsequent "non-simple" definition of FOO,
where FOO had been proclaimed "simple", should signal an error or warning.
Of course, not every compiler and/or interpreter is capable of enough
analysis to distinguish "simple" from "non-simple" from "unknown"; this is
in the realm of "user-friendly" rather than language semantics.
-- JonL --
∂16-May-88 1619 Common-Lisp-mailer Re: Constant-Function, and integration-level
Received: from PECAN.CS.ROCHESTER.EDU ([192.5.53.206]) by SAIL.Stanford.EDU with TCP; 16 May 88 16:19:14 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by PECAN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 2738; Mon 16-May-88 19:13:54 EDT
Date: Mon, 16 May 88 19:13 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: Constant-Function, and integration-level
To: Gail Zacharias <gz@spt.entity.com>
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805131805.AA17354@spt.entity.com>
Message-ID: <19880516231342.7.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: 13 May 88 18:05:52 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
Clearly any decent development environment should not 'lock in' functions
during development. But that's not a question that a language standard
need address, it's something between you and your Lisp vendor...
Here we disagree. If any progress has been made in software engineering in
the past decade, it is probably to approach agreement that software reuse is
very important. When vendor delivers me software, I should be able to simply
and easily modify said work to my needs. I'm not going to be able to do that
if the implementation of the language defines the loaded code to be static.
Of course, by this standard, delivery of binary-only systems is useless. A
position I'm prepared to defend.
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂16-May-88 1703 Common-Lisp-mailer Re: replies to hash table comments
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 16 May 88 17:03:34 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 16 MAY 88 17:00:26 PDT
Date: Mon, 16 May 88 17:00:17 PDT
From: Pavel.pa@Xerox.COM
Subject: Re: replies to hash table comments
In-reply-to: <12398139318.17.TOURETZKY@C.CS.CMU.EDU>
To: Dave.Touretzky@C.CS.CMU.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <880516-170026-1599@Xerox>
Would the input
#H(EQUAL (FOO 7) (BAR 8))
be equivalent to the input
#H(EQUAL (FOO . (7)) (BAR . (8)))
or simply illegal? If the former, I'm left a bit queasy, I think, but I'm not
sure why. If the latter, then why use dot notation?
Pavel
∂16-May-88 1802 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 16 May 88 18:02:12 PDT
Received: by labrea.stanford.edu; Mon, 16 May 88 18:02:37 PDT
Received: from bhopal.lucid.com by edsel id AA27337g; Mon, 16 May 88 17:52:07 PDT
Received: by bhopal id AA02396g; Mon, 16 May 88 17:55:30 PDT
Date: Mon, 16 May 88 17:55:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805170055.AA02396@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Fri, 13 May 88 16:00 EDT <8805140852.AA16784@edsel.lucid.com>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
re: . . . Should "ERROR" and
"CERROR" be considered side effect free for this purpose?
If not then functions like division can't be considered side
effect free, since division by zero must signal an error.
Hmmm, I think you've hit upon a good question. The only way I can around
the problem is to define these kinds of properties of a function based on
"correct" arguments, and without regard to asynchronous interrupts. After
all, in virtually every implementation, you could interrupt almost any old
random function, and cause whatever malevolent side-effects you want. Thus
division should be considered "simple", even though there is a legal path
through it that calls a function with probable side-effects.
re: . . . if a compiler can check these properties it could
also compute them. But currently it would not be allowed
to use those computed properties.
I agree with you that a compiler (and maybe even interpreter?) should do as
much consistency checking as possible. As moon implied in previous mail,
an SSC(*) should be able to determine "simpleness" mechanically. But the
danger of using that information is that it may not have been the user's
_intent_ that this function be marked as "simple" (e.g., he may want to
alter it incompatibly at a later time). An explicit proclamation (or
whatever) is the right vehicle for conveying that intent.
One more interesting question related to what is STATELESS arises out
of noting the distinction drawn between Symbolic's declarations
(LT:SIDE-EFFECTS LT:REDUCIBLE) and (LT:SIDE-EFFECTS LT:SIMPLE REDUCIBLE).
Is CAR STATELESS? I say yes, even though the Symbolics terminology
seems to imply that it is sensitive to side-effects. In the example:
(let ((x (list '1 '2)))
(print (CAR (cdr x))) [1]
(rplaca (cdr x) '3) [2]
(print (CAR (cdr x)))) [3]
One might be tempted to say that CAR is sensitive to the side-effect on
line [2]; but it certainly isn't sensitive to side-effects the way INTERN
is sensitive to the setting of *PACKAGE*. That is, no state other than
the argument is needed to produce the result. What is going on here is
that two _different_ arguments are being given to CAR at two different
times (times [1] and [3]); even though they appear to be EQ at the times
of call, they are not EQUAL, and that is the equivalence of importance when
talking about list accessors. (EQ but not EQUAL -- quite iconoclastic, no?).
So, I would prefer to say that the argument to CAR can be modified by
side-effecting functions; hence a compiler must keep track not only of the
properties of the function it is compiling a call to, but also of the
potential alterations to the arguments to that function. The same analysis
applies to arrays, hash-tables, defstructs and so on, as well as to cons cells.
By contrast, the arguments to + cannot be modified by any CLtL function,
and this is presumably what LT:SIMPLE adds to LT:REDUCIBLE for Symbolics.
[Remember my previous note about SETN in Interlisp?]. Unfortunately, there
aren't many read-only datatypes in Common Lisp.
-- JonL --
(*) SSC -- acronym for "Sufficiently Smart Compiler"
∂16-May-88 1834 Common-Lisp-mailer #H syntax
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 16 May 88 18:34:16 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Mon 16 May 88 21:34:01-EDT
Date: Mon 16 May 88 21:34:00-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: #H syntax
To: common-lisp@SAIL.STANFORD.EDU
cc: pavel.pa@XEROX.COM, Dave.Touretzky@C.CS.CMU.EDU
Message-ID: <12398904023.12.TOURETZKY@C.CS.CMU.EDU>
> From: Pavel.pa@Xerox.COM
> Would the input
> #H(EQUAL (FOO 7) (BAR 8))
> be equivalent to the input
> #H(EQUAL (FOO . (7)) (BAR . (8)))
> or simply illegal? If the former, I'm left a bit queasy, I think, but I'm
> not sure why. If the latter, then why use dot notation?
I wanted the syntax of hash table elements in #H to mirror the syntax
of a-lists, since hash tables and a-lists are semantically similar
and provide similar functionality in Common Lisp. So my proposal is for
the former alternative, i.e., (FOO 7) would be treated as (FOO . (7)).
I understand Pavel's queasiness on this point. For a while I considered
using list syntax instead of dotted pair syntax, because the dots look
kind of messy and require two extra characters per table entry.
I'm happy to leave the exact choice of syntax up to the cleanup committee. If
no one else has objections or suggestions, I will submit a proposal to the
cleanup committee using the dot notation and mention the list notation version
as a possible alternative.
-- Dave
-------
∂16-May-88 1941 Common-Lisp-mailer #H syntax
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 16 May 88 18:34:16 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Mon 16 May 88 21:34:01-EDT
Date: Mon 16 May 88 21:34:00-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: #H syntax
To: common-lisp@SAIL.STANFORD.EDU
cc: pavel.pa@XEROX.COM, Dave.Touretzky@C.CS.CMU.EDU
Message-ID: <12398904023.12.TOURETZKY@C.CS.CMU.EDU>
> From: Pavel.pa@Xerox.COM
> Would the input
> #H(EQUAL (FOO 7) (BAR 8))
> be equivalent to the input
> #H(EQUAL (FOO . (7)) (BAR . (8)))
> or simply illegal? If the former, I'm left a bit queasy, I think, but I'm
> not sure why. If the latter, then why use dot notation?
I wanted the syntax of hash table elements in #H to mirror the syntax
of a-lists, since hash tables and a-lists are semantically similar
and provide similar functionality in Common Lisp. So my proposal is for
the former alternative, i.e., (FOO 7) would be treated as (FOO . (7)).
I understand Pavel's queasiness on this point. For a while I considered
using list syntax instead of dotted pair syntax, because the dots look
kind of messy and require two extra characters per table entry.
I'm happy to leave the exact choice of syntax up to the cleanup committee. If
no one else has objections or suggestions, I will submit a proposal to the
cleanup committee using the dot notation and mention the list notation version
as a possible alternative.
-- Dave
-------
∂16-May-88 2357 Common-Lisp-mailer visible hash tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 16 May 88 23:56:53 PDT
Received: by labrea.stanford.edu; Mon, 16 May 88 23:57:19 PDT
Received: from bhopal.lucid.com by edsel id AA28941g; Mon, 16 May 88 23:48:33 PDT
Received: by bhopal id AA03483g; Mon, 16 May 88 23:51:57 PDT
Date: Mon, 16 May 88 23:51:57 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805170651.AA03483@bhopal.lucid.com>
To: MLY@ai.ai.mit.edu
Cc: Dave.Touretzky@c.cs.cmu.edu, common-lisp@sail.stanford.edu
In-Reply-To: Richard Mlynarik's message of Fri, 13 May 88 09:14 EDT <19880513131438.3.MLY@JACKIE.AI.MIT.EDU>
Subject: visible hash tables
I think you've made a useful observation that there a whole slew of potential
(or real) data types in CLtL for which there is no commonly accepted print
syntax, and for which the #S syntax could be naturally extended to cover.
BYTE-SPECIFIER comes to mind, as well as RANDOM-STATE, PATHNAME, HASH-TABLE,
PACKAGE, READTABLE, STREAM, (compiled) FUNCTION, and non-simple ARRAY and
ARRAY with specialized element-type not among {'bit', 'string-char', 'T'}.
On the other hand, I may have to argue against this unifying approach in at
least one or more of the important cases at hand. Lucid, like Symbolics,
already uses the #P"..." approach to pathnames, and probably wouldn't like
to go to a more space-wasting format. And for "database"-like types such
as packages and streams, using something like #S would be a gross over-
simplification; recursive descent throught the slots would indubitably
have incestuous circularities.
Incidentally, both you and Touretzky forgot that hash-tables have two
additional interesting properties beyond the :type and :size -- the
:rehash-size and :rehash-threshold. Hash-tables wouldn't be fully
reconstructable from the printed format unless this information were
also included.
-- JonL --
∂17-May-88 0008 Common-Lisp-mailer Re: visible hash tables
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 17 May 88 00:07:54 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Tue 17 May 88 03:07:41-EDT
Date: Tue 17 May 88 03:07:40-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: Re: visible hash tables
To: edsel!jonl@LABREA.STANFORD.EDU
cc: MLY@AI.AI.MIT.EDU, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805170651.AA03483@bhopal.lucid.com>
Message-ID: <12398964767.12.TOURETZKY@C.CS.CMU.EDU>
I'm didn't forget that hash tables have other parameters besides :type and
:size. I just didn't think it appropriate to include them in the #H notation,
in part because they're likely to be implementation-dependent.
For that matter, you can't fully reconstruct vectors and arrays from the #()
and #A notations either, since they omit properties like whether or not the
vector has a fill pointer, whether the array is adjustable or not, and whether
the array is one of :element-type T or some more restricted type.
-- Dave
-------
∂17-May-88 0101 Common-Lisp-mailer Re: visible hash tables
Received: from SKEF.SLISP.CS.CMU.EDU ([128.2.218.47]) by SAIL.Stanford.EDU with TCP; 17 May 88 01:01:14 PDT
Received: from SKEF.SLISP.CS.CMU.EDU by SKEF.SLISP.CS.CMU.EDU; 17 May 88 04:02:25 EDT
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: MLY@ai.ai.mit.edu, Dave.Touretzky@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
Subject: Re: visible hash tables
In-reply-to: Your message of Mon, 16 May 88 23:51:57 -0700.
<8805170651.AA03483@bhopal.lucid.com>
Date: Tue, 17 May 88 04:02:15 EDT
From: Skef.Wholey@SPICE.CS.CMU.EDU
From: Jon L White <edsel!jonl@labrea.stanford.edu>
[...] there a whole slew of potential (or real) data types in CLtL for
which there is no commonly accepted print syntax [...] BYTE-SPECIFIER
comes to mind, as well as RANDOM-STATE, PATHNAME, [...] and non-simple
ARRAY and ARRAY with specialized element-type [...]
Lucid, like Symbolics, already uses the #P"..." approach to pathnames
[...]
[...] hash-tables have two additional interesting properties beyond the
:type and :size -- the :rehash-size and :rehash-threshold. Hash-tables
wouldn't be fully reconstructable from the printed format unless this
information were also included.
Ok, Crazy 3:39 AM Idea: CMU-CL prints pathnames out as #.(pathname
"/usr/foo/bar"). I think this was done as a quick hack to satisfy the
requirement that pathnames print out readably, and that the writer of
that code had never seen the #P syntax. BUT: the idea of using #. in
printing could be incorporated to preserve such things as array element
type in array printing. Then, if things like Make-Hash-Table were to be
modified to take :Initial-Elements keyword args, ala Make-Array, the
problem of preserving things like Rehash-Size and Rehash-Threshold could
be easily solved in a consistent, centralized way, using the
user-visible construction functions rather than a bizzare extension to
#S, which would have many weird special cases to document and implement.
One can (if one tries) envision a super printer switch,
*Print-It-Like-It-Is*, which would cause things to print out in an ugly
but information-laden way, preserving all the things that (we think)
ought to be preserved.
Now, it would be especially neato if *Print-It-Like-It-Is* printed
things in a \portable/ way, so that a hash table (or pathname!) printed
under Lucid CL could be read by any other CL. #P is obviously not
portable. (What use would people have in wanting pathnames to be
portable? Well, just today I heard a user ask a CMU-CL implementor
about having Lucid CL on a Sun talk to CMU-CL on an RT. Among other
things, these two Lisps share the same network file system, and so
passing pathnames back and forth is a sensible thing...)
--Skef
∂17-May-88 0133 Common-Lisp-mailer Re: visible hash tables
Received: from SKEF.SLISP.CS.CMU.EDU ([128.2.218.47]) by SAIL.Stanford.EDU with TCP; 17 May 88 01:01:14 PDT
Received: from SKEF.SLISP.CS.CMU.EDU by SKEF.SLISP.CS.CMU.EDU; 17 May 88 04:02:25 EDT
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: MLY@ai.ai.mit.edu, Dave.Touretzky@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
Subject: Re: visible hash tables
In-reply-to: Your message of Mon, 16 May 88 23:51:57 -0700.
<8805170651.AA03483@bhopal.lucid.com>
Date: Tue, 17 May 88 04:02:15 EDT
From: Skef.Wholey@SPICE.CS.CMU.EDU
From: Jon L White <edsel!jonl@labrea.stanford.edu>
[...] there a whole slew of potential (or real) data types in CLtL for
which there is no commonly accepted print syntax [...] BYTE-SPECIFIER
comes to mind, as well as RANDOM-STATE, PATHNAME, [...] and non-simple
ARRAY and ARRAY with specialized element-type [...]
Lucid, like Symbolics, already uses the #P"..." approach to pathnames
[...]
[...] hash-tables have two additional interesting properties beyond the
:type and :size -- the :rehash-size and :rehash-threshold. Hash-tables
wouldn't be fully reconstructable from the printed format unless this
information were also included.
Ok, Crazy 3:39 AM Idea: CMU-CL prints pathnames out as #.(pathname
"/usr/foo/bar"). I think this was done as a quick hack to satisfy the
requirement that pathnames print out readably, and that the writer of
that code had never seen the #P syntax. BUT: the idea of using #. in
printing could be incorporated to preserve such things as array element
type in array printing. Then, if things like Make-Hash-Table were to be
modified to take :Initial-Elements keyword args, ala Make-Array, the
problem of preserving things like Rehash-Size and Rehash-Threshold could
be easily solved in a consistent, centralized way, using the
user-visible construction functions rather than a bizzare extension to
#S, which would have many weird special cases to document and implement.
One can (if one tries) envision a super printer switch,
*Print-It-Like-It-Is*, which would cause things to print out in an ugly
but information-laden way, preserving all the things that (we think)
ought to be preserved.
Now, it would be especially neato if *Print-It-Like-It-Is* printed
things in a \portable/ way, so that a hash table (or pathname!) printed
under Lucid CL could be read by any other CL. #P is obviously not
portable. (What use would people have in wanting pathnames to be
portable? Well, just today I heard a user ask a CMU-CL implementor
about having Lucid CL on a Sun talk to CMU-CL on an RT. Among other
things, these two Lisps share the same network file system, and so
passing pathnames back and forth is a sensible thing...)
--Skef
∂17-May-88 0745 Common-Lisp-mailer visible hash tables
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 May 88 07:45:33 PDT
Return-Path: <rose@Think.COM>
Received: from brigit.think.com by Think.COM; Tue, 17 May 88 10:42:04 EDT
Received: by brigit.think.com; Tue, 17 May 88 10:42:01 EDT
Date: Tue, 17 May 88 10:42:01 EDT
From: rose@Think.COM
Message-Id: <8805171442.AA02649@brigit.think.com>
To: edsel!jonl@labrea.stanford.edu
Cc: MLY@ai.ai.mit.edu, Dave.Touretzky@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Mon, 16 May 88 23:51:57 PDT <8805170651.AA03483@bhopal.lucid.com>
Subject: visible hash tables
Date: Mon, 16 May 88 23:51:57 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
I think you've made a useful observation that there a whole slew of potential
(or real) data types in CLtL for which there is no commonly accepted print
syntax, and for which the #S syntax could be naturally extended to cover.
BYTE-SPECIFIER comes to mind, as well as RANDOM-STATE, PATHNAME, HASH-TABLE,
PACKAGE, READTABLE, STREAM, (compiled) FUNCTION, and non-simple ARRAY and
ARRAY with specialized element-type not among {'bit', 'string-char','T'}.
Having a print function presumes having a dynamically distinguishable
type. If BYTE-SPECIFIER is implemented as an integer, you might have
a read syntax for it, but you couldn't expect it to print that way.
(Actually, the Genera 7 PRESENT function allows an optional
type argument for just this purpose.)
On the other hand, I may have to argue against this unifying approach in at
least one or more of the important cases at hand. Lucid, like Symbolics,
already uses the #P"..." approach to pathnames, and probably wouldn't like
to go to a more space-wasting format. And for "database"-like types such
as packages and streams, using something like #S would be a gross over-
simplification; recursive descent throught the slots would indubitably
have incestuous circularities.
Right. You don't want to print an object's implementation. You want
to print something which has a fighting chance of being interpreted
by any Common Lisp, using only CLtL functions.
Incidentally, both you and Touretzky forgot that hash-tables have two
additional interesting properties beyond the :type and :size -- the
:rehash-size and :rehash-threshold. Hash-tables wouldn't be fully
reconstructable from the printed format unless this information were
also included.
-- JonL --
A well-designed #H syntax would be open-ended enough to include all
sorts of info on the hash table. Since a hash table is created by
a call to MAKE-HASH-TABLE, followed by any number of calls to
(SETF GETHASH), the form following the #H should be able to contain
all the arguments of those calls. The format that appeals to
me has one list element per call, each giving the arguments
for that call apart from the table itself:
#H((:test 'eql :size 10) (:blue #(0 0 10)) (:red #(10 0 0)))
Perhaps if the first form is an atom X, it should be taken to mean
(:test X); this supports an earlier proposal as a special case.
Probably if an implementation puts non-standard keywords into the
first list, it should also put in :allow-other-keys t.
There's an obvious generalization here to other "container types",
especially arrays: Their P.R.'s should recapitulate their creation.
By "container type" I mean that the meaning of such an object depends
only on its connections to a set of pre-existing objects, which were
associated with it in the course of its creation. In particular, its
meaning must not depend on objects which refer to it; i.e., there must
be no visible "back pointers". By "meaning" I mean that which is
preserved by the P.R. It's all pretty loose.
-- John
∂17-May-88 0858 Common-Lisp-mailer visible hash tables
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 May 88 08:58:22 PDT
Received: from fafnir.think.com by Think.COM; Tue, 17 May 88 11:56:27 EDT
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by fafnir.think.com; Tue, 17 May 88 11:56:24 EDT
Date: Tue, 17 May 88 11:58 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: visible hash tables
To: Jon L White <edsel!jonl@labrea.stanford.edu>
Cc: MLY@ai.ai.mit.edu, Dave.Touretzky@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <8805170651.AA03483@bhopal.lucid.com>
Message-Id: <19880517155802.0.BARMAR@OCCAM.THINK.COM>
Date: Mon, 16 May 88 23:51:57 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Incidentally, both you and Touretzky forgot that hash-tables have two
additional interesting properties beyond the :type and :size -- the
:rehash-size and :rehash-threshold. Hash-tables wouldn't be fully
reconstructable from the printed format unless this information were
also included.
That's not an unprecedented flaw. Arrays have a number of properties
that are not represented in their printed representations, such as
adjustability, fill pointer, and element type.
barmar
∂17-May-88 1217 Common-Lisp-mailer RE: Visible Hash-Tables
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 17 May 88 12:16:59 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ah04568; 17 May 88 13:38 EDT
Received: from cs.umass.edu by RELAY.CS.NET id ad05674; 17 May 88 13:24 EDT
Date: Tue, 17 May 88 10:05 EDT
From: ELIOT@cs.umass.edu
Subject: RE: Visible Hash-Tables
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
Both INSPECT and DESCRIBE are "standard" CLtL functions. The results
are not READable, but the original question was for a way to allow
students to look inside hash-tables. INSPECT may be too complex
for students (I don't use INSPECT) but DESCRIBE should not be.
However, CLtL does not specify that either of these functions will
show you the content of Hash-Tables. Would it be resonable to
specify for each data type what is the minimal information that
these functions must show? Better still for DESCRIBE, at least,
would be a portable public domain implementation.
I think a more detailed specification of DESCRIBE and INSPECT
would be useful. I have been disapointed because information
was not printed that *obviously* (to me) should have been.
A standard could list the components of compound objects that
must be printed, without trying to specify the format.
∂17-May-88 1336 Common-Lisp-mailer (aside about) visible hash tables
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 17 May 88 13:36:03 PDT
Received: from PEWEE.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 406207; Tue 17-May-88 16:34:11 EDT
Date: Tue, 17 May 88 16:34 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: (aside about) visible hash tables
To: rose@Think.COM
cc: edsel!jonl@labrea.stanford.edu, MLY@ai.ai.mit.edu,
Dave.Touretzky@c.cs.cmu.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8805171442.AA02649@brigit.think.com>
Message-ID: <880517163400.6.KMP@PEWEE.SCRC.Symbolics.COM>
Date: Tue, 17 May 88 10:42:01 EDT
From: rose@Think.COM
Date: Mon, 16 May 88 23:51:57 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
I think you've made a useful observation that there a whole slew of potential
(or real) data types in CLtL for which there is no commonly accepted print
syntax, and for which the #S syntax could be naturally extended to cover.
BYTE-SPECIFIER comes to mind, as well as RANDOM-STATE, PATHNAME, HASH-TABLE,
PACKAGE, READTABLE, STREAM, (compiled) FUNCTION, and non-simple ARRAY and
ARRAY with specialized element-type not among {'bit', 'string-char','T'}.
Having a print function presumes having a dynamically distinguishable
type. If BYTE-SPECIFIER is implemented as an integer, you might have
a read syntax for it, but you couldn't expect it to print that way.
...
Well, you couldn't expect it in all possible universes, but you could in some.
The following technique works for at least some implementations and is provided
only for color in this discussion. The main thrust of your point is, of course,
correct.
In Maclisp, we had the problem that people wanted a read macro #/A which
read in as 65 for use in programs, but the problem is that it didn't pretty
print well. Maclisp only `interned' small fixnums, so I once wrote a facility
that generated uninterned small fixnums by adding 1 to a large fixnum (to get
a fresh FIXNUM cell) and then bashing a small number back into the `cdr' of
the fixnum. Then I filled an array of numbers from 0-127 with small fixnums
whose values were 0-127, respectively, but which were not EQ to the normal
0-127. I could then do
(DEFUN READ-CHAR (STREAM) (ARRAYCALL T THE-CHARS (TYI STREAM)))
(DEFUN CHAR= (CHAR1 CHAR2) (= CHAR1 CHAR2))
(DEFUN CHARACTERP (CHAR)
(AND (FIXNUMP CHAR)
(< -1 CHAR 128)
(EQ (ARRAYCALL T THE-CHARS CHAR) CHAR))) ;Use of EQ is critical
(DEFUN CHAR-CODE (CHAR) (+ CHAR 0))
(DEFUN CODE-CHAR (CHAR) (ARRAYCALL T THE-CHARS CHAR))
...etc.
In this way, an integer could be used to represent a character but the fact
that the data object was a character was still preserved. This allowed me to
extend the pretty printer so that #/A would print as #/A and 65 would print as
65 even though
(LET ((X1 #/A) (X2 65))
(AND (EQ (TYPEP X1) 'FIXNUM)
(EQ (TYPEP X2) 'FIXNUM)
(= X1 X2)))
was true. You just had to be sure that CHARACTERP tests always preceded number
tests and you were all set...
Similarly, one could imagine a particular CL implementation which chose to
implement byte pointers as fixnums (and which did not represent fixnums
immediately) might have done:
(DEFMACRO CACHED-BYTE-SIZE (SIZE POSITION)
;there are -definitely- more time-efficient and GC-efficient ways to do
;this but this gets the abstract idea across just fine.
`(GETHASH (LIST SIZE POSITION) *THE-BYTE-SIZES*))
(DEFUN BYTE (SIZE POSITION)
(OR (CACHED-BYTE SIZE POSITION)
(SETF (CACHED-BYTE SIZE POSITION)
(MAKE-UNIQUE-FIXNUM (BYTE-INTERNAL SIZE POSITION)))))
(DEFUN BYTE-INTERNAL (SIZE POSITION)
...fool around with LOGIOR, ASH, etc...)
(DEFUN MAKE-UNIQUE-FIXNUM (VALUE)
...implementation would vary and would only be possible on systems
which didn't represent fixnums immediately...)
∂17-May-88 1514 Common-Lisp-mailer RE: Visible Hash-Tables
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 17 May 88 15:14:05 PDT
Received: from fafnir.think.com by Think.COM; Tue, 17 May 88 18:12:08 EDT
Return-Path: <barmar@Think.COM>
Received: from OCCAM.THINK.COM by fafnir.think.com; Tue, 17 May 88 18:12:05 EDT
Date: Tue, 17 May 88 18:13 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: RE: Visible Hash-Tables
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8805172053.AA11503@Think.COM>
Message-Id: <19880517221347.5.BARMAR@OCCAM.THINK.COM>
Date: Tue, 17 May 88 10:05 EDT
From: ELIOT@cs.umass.edu
Both INSPECT and DESCRIBE are "standard" CLtL functions. The results
are not READable, but the original question was for a way to allow
students to look inside hash-tables. INSPECT may be too complex
for students (I don't use INSPECT) but DESCRIBE should not be.
However, CLtL does not specify that either of these functions will
show you the content of Hash-Tables. Would it be resonable to
specify for each data type what is the minimal information that
these functions must show? Better still for DESCRIBE, at least,
would be a portable public domain implementation.
Until we define CL functions for examining defstruct structures (e.g. a
function that takes a structure name and returns a list of slot accessor
functions) it will not be possible to write a portable DESCRIBE that can
tell you the contents of a structure. Also, there are no accessors
at all for some other types, such as RANDOM-STATE and HASH-TABLE (and
this is the one that prompted this discussion).
One of the reasons that DESCRIBE is part of the standard is because it
is impossible to write a useful version of it using the existing
accessors.
barmar
∂17-May-88 1628 Common-Lisp-mailer [portable pathname formats] visible hash tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 17 May 88 16:28:05 PDT
Received: by labrea.stanford.edu; Tue, 17 May 88 16:28:32 PDT
Received: from bhopal.lucid.com by edsel id AA02356g; Tue, 17 May 88 16:18:48 PDT
Received: by bhopal id AA06440g; Tue, 17 May 88 16:22:13 PDT
Date: Tue, 17 May 88 16:22:13 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805172322.AA06440@bhopal.lucid.com>
To: Skef.Wholey@SPICE.CS.CMU.EDU
In-Reply-To: Skef.Wholey@SPICE.CS.CMU.EDU's message of Tue, 17 May 88 04:02:15 EDT <8805170836.AA29487@edsel.lucid.com>
Cc: common-lisp@sail.stanford.edu
Subject: [portable pathname formats] visible hash tables
re: Well, just today I heard a user ask a CMU-CL implementor
about having Lucid CL on a Sun talk to CMU-CL on an RT. Among other
things, these two Lisps share the same network file system, and so
passing pathnames back and forth is a sensible thing...)
Symbolics has something like"logical pathnames"; I'm not familiar enough with
it to comment on whether or not that approach is satisfactory. Are you?
Although this issue is a bit off the direction of printing random structure
like things, it is still a very important one, especially as multi-vendor
networks spring up. See Mar 88 issue of CACM with articles on heterogeneous
network/operating systems.
-- JonL --
P.S. Glad to see someone else hacking at "3:39 AM"!
∂17-May-88 2300 Common-Lisp-mailer visible hash tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 17 May 88 23:00:40 PDT
Received: by labrea.stanford.edu; Tue, 17 May 88 23:01:05 PDT
Received: from bhopal.lucid.com by edsel id AA03524g; Tue, 17 May 88 22:49:40 PDT
Received: by bhopal id AA07807g; Tue, 17 May 88 22:53:07 PDT
Date: Tue, 17 May 88 22:53:07 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805180553.AA07807@bhopal.lucid.com>
To: barmar@think.com
Cc: MLY@ai.ai.mit.edu, Dave.Touretzky@c.cs.cmu.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Tue, 17 May 88 11:58 EDT <19880517155802.0.BARMAR@OCCAM.THINK.COM>
Subject: visible hash tables
re: That's not an unprecedented flaw. Arrays have a number of properties
that are not represented in their printed representations, such as
adjustability, fill pointer, and element type.
Not all arrays have these properties; contrast that with all hashtables
having the rehash-size and rehash-threshold slots.
I think my message did address the question about arrays, in the first
paragraph, when enumerating the types that don't have adequate print
representations and for which MLY's suggestion might be a solution:
". . . and non-simple ARRAY and ARRAY with specialized element-type
not among {'bit', 'string-char', 'T'}."
-- JonL --
∂18-May-88 0000 Common-Lisp-mailer Visible Hash-Tables
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 18 May 88 00:00:27 PDT
Received: by labrea.stanford.edu; Wed, 18 May 88 00:00:41 PDT
Received: from bhopal.lucid.com by edsel id AA03695g; Tue, 17 May 88 23:51:46 PDT
Received: by bhopal id AA07983g; Tue, 17 May 88 23:55:13 PDT
Date: Tue, 17 May 88 23:55:13 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805180655.AA07983@bhopal.lucid.com>
To: barmar@think.com
Cc: ELIOT@cs.umass.edu, common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Tue, 17 May 88 18:13 EDT <19880517221347.5.BARMAR@OCCAM.THINK.COM>
Subject: Visible Hash-Tables
re: . . . Also, there are no accessors
at all for some other types, such as RANDOM-STATE and HASH-TABLE (and
this is the one that prompted this discussion).
Guy Steele's "Clarifications" of December 6, 1985 added the necessary,
missing accessors for hash-tables: HASH-TABLE-TEST, HASH-TABLE-SIZE,
HASH-TABLE-REHASH-SIZE, and HASH-TABLE-REHASH-THRESHOLD. Lucid's
implementation added them almost immediately, although documentation
about their existence is somewhat recent.
These "Clarifications" were presented at the meeting which founded X3J13 --
for ANSI standardization of Common Lisp -- and represented a consensus
amongst the community back then. There was some subsequent discussion of
the points on this mailing list shortly after that meeting.
One unfortunate lacuna in the x3j13 "cleanup" committee's work is that there
is no explicit statement about the validity of Steele's "Clarifications".
In fact, most of the individual "Clarifications" haven't been specifically
and individually addressed.
-- JonL --
∂18-May-88 1112 Common-Lisp-mailer request to change my mailing address
Received: from XN.LL.MIT.EDU by SAIL.Stanford.EDU with TCP; 18 May 88 11:11:52 PDT
Received: by XN.LL.MIT.EDU; Wed, 18 May 88 08:22:14 EDT
Date: Wed, 18 May 88 08:22:14 EDT
From: walton@XN.LL.MIT.EDU (Robert Walton)
Posted-Date: Wed, 18 May 88 08:22:14 EDT
Message-Id: <8805181222.AA24880@XN.LL.MIT.EDU>
To: common-lisp@sail.stanford.edu
Cc: walton@XN.LL.MIT.EDU, glenn@XN.LL.MIT.EDU, cogen@XN.LL.MIT.EDU
Subject: request to change my mailing address
Would you replace walton@vlsi.ll.mit.edu (or maybe its ll-vlsi.arpa) by
commonlisp-mail@xn.ll.mit.edu
which will reach me and others. Also, if you could help add
commonlisp-objects-mail@xn.ll.mit.edu
to the CLOS mailing list I've heard tell of, and add
commonlisp-windows-mail@xn.ll.mit.edu
to the CL WINDOWS mailing list I think may exist, I'd be much appreciative.
Thanks,
Bob Walton
∂18-May-88 1853 Common-Lisp-mailer visible hash table nit
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 18 May 88 18:53:06 PDT
Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Wed 18 May 88 20:52:59-CDT
Date: Wed, 18 May 88 20:52 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: visible hash table nit
To: common-lisp@sail.stanford.edu
Message-ID: <880518205254.1.GUMBY@BRAHMA.ACA.MCC.COM>
Could you use #T instead of #H?
Right now symbolics uses make-hash-table as an interface to a system
which uses an "appropriate" representation for the size of the table
(alist or hash-table only, I think.) One could imagine an
implementation which build a b-tree or whatever of its data (which would
still fit the GETHASH model, but wouldn't be a hash table in the strict
sense).
Touretzky, I don't know about your pedagogical needs (are you teaching
hashing functions too, or are they just a "black box" to your students?)
but in general it's better to hide the implementation from the user, and
a sort of a generic table representation seems "right."
Plus, I use #H for hosts.
david
∂18-May-88 1858 Common-Lisp-mailer Features
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 18 May 88 18:58:30 PDT
Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Wed 18 May 88 20:58:25-CDT
Date: Wed, 18 May 88 20:58 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: Features
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8805102102.AA16844@bhopal.lucid.com>
Message-ID: <880518205815.3.GUMBY@BRAHMA.ACA.MCC.COM>
Date: Tue, 10 May 88 14:02:42 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
X3J13 is considering a proposal to require the setting of *package* to be
the KEYWORD package during the scope of reading the forms under a #+ or a
#-. This will tend to give the appearance of "namestring" comparison rather
than EQ only because, for example, #+LUCID will be read in the feature as
:LUCID, and the search on *features* will be for that symbol. The X3J13
proposal would permit reading in feature names like #+MACSYMA:HYPERLINEAR,
in which case the member test would be with the symbol MACSYMA:HYPERLINEAR.
What do you do if you encounter #+nasa:hyperdrive but you don't have the
nasa package defined?
∂18-May-88 2118 Common-Lisp-mailer Re: visible hash table nit
Received: from C.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 18 May 88 21:18:38 PDT
Received: ID <TOURETZKY@C.CS.CMU.EDU.#Internet>; Thu 19 May 88 00:18:06-EDT
Date: Thu 19 May 88 00:18:05-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
Subject: Re: visible hash table nit
To: Gumby@MCC.COM
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <880518205254.1.GUMBY@BRAHMA.ACA.MCC.COM>
Message-ID: <12399458184.18.TOURETZKY@C.CS.CMU.EDU>
I think we should stick with #H unless the Common Lisp cleanup committee
decides to eliminate the word "hash" from the language. Right now, everyone
calls them "hash tables", not "tables", and "hash" is built into the language
in lots of places, e.g., GETHASH, MAKE-HASH-TABLE, HASH-TABLE (as a type
specifier), :REHASH-SIZE, and so on. So #H is mnemonic; #T would not be for
most readers.
-- Dave
-------
∂19-May-88 0043 Common-Lisp-mailer Features
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 19 May 88 00:42:54 PDT
Received: by labrea.stanford.edu; Thu, 19 May 88 00:43:17 PDT
Received: from bhopal.lucid.com by edsel id AA09223g; Thu, 19 May 88 00:11:16 PDT
Received: by bhopal id AA11771g; Thu, 19 May 88 00:14:48 PDT
Date: Thu, 19 May 88 00:14:48 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805190714.AA11771@bhopal.lucid.com>
To: Gumby@mcc.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: David Vinayak Wallace's message of Wed, 18 May 88 20:58 CDT <880518205815.3.GUMBY@BRAHMA.ACA.MCC.COM>
Subject: Features
re: What do you do if you encounter #+nasa:hyperdrive but you don't have the
nasa package defined?
If an alleged feature name "doesn't exist", that means that the feature
isn't present [and it can fail to "exist" in several different ways].
This is the behaviour Lucid implements, and I'm sure I saw some network
mail a long time ago agreeing to this meaning. But I don't see any
statement about this case in the X3J13 CLeanup Committee's issue
SHARPSIGN-PLUS-MINUS-PACKAGE. Kent? Larry?
-- JonL --
∂19-May-88 0738 Common-Lisp-mailer Features
Received: from DIAMOND.S4CC.Symbolics.COM ([128.81.51.3]) by SAIL.Stanford.EDU with TCP; 19 May 88 07:38:16 PDT
Received: from CHURCH.S4CC.Symbolics.COM by DIAMOND.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 190873; Thu 19-May-88 10:33:26 EDT
Date: Thu, 19 May 88 10:33 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Features
To: Gumby@MCC.COM, edsel!jonl@labrea.stanford.edu
cc: common-lisp@sail.stanford.edu
In-Reply-To: <880518205815.3.GUMBY@BRAHMA.ACA.MCC.COM>
Message-ID: <19880519143304.7.GREENWALD@CHURCH.S4CC.Symbolics.COM>
Date: Wed, 18 May 88 20:58 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Date: Tue, 10 May 88 14:02:42 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
X3J13 is considering a proposal to require the setting of *package* to be
the KEYWORD package during the scope of reading the forms under a #+ or a
#-. This will tend to give the appearance of "namestring" comparison rather
than EQ only because, for example, #+LUCID will be read in the feature as
:LUCID, and the search on *features* will be for that symbol. The X3J13
proposal would permit reading in feature names like #+MACSYMA:HYPERLINEAR,
in which case the member test would be with the symbol MACSYMA:HYPERLINEAR.
What do you do if you encounter #+nasa:hyperdrive but you don't have the
nasa package defined?
The Symbolics' reader allows the use of package qualified symbols for
features. If no package is present the symbol is assumed to be in the
keyword package. If a symbol is in an undefined package then the
feature is considered "not present", so #- is true, and #+ is false.
∂19-May-88 0813 Common-Lisp-mailer Readable Hash-Tables
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 19 May 88 08:12:51 PDT
Received: from relay2.cs.net by RELAY.CS.NET id bv08365; 19 May 88 8:24 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bq18331; 19 May 88 3:53 EDT
Date: Wed, 18 May 88 12:35 EDT
From: ELIOT@cs.umass.edu
Subject: Readable Hash-Tables
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: Barry Margolin <barmar@think.COM>
Better still for DESCRIBE, at least,
would be a portable public domain implementation.
Until we define CL functions for examining defstruct structures (e.g. a
function that takes a structure name and returns a list of slot accessor
functions) it will not be possible to write a portable DESCRIBE that can
tell you the contents of a structure. Also, there are no accessors
at all for some other types, such as RANDOM-STATE and HASH-TABLE (and
this is the one that prompted this discussion).
One of the reasons that DESCRIBE is part of the standard is because it
is impossible to write a useful version of it using the existing
accessors.
barmar
I was aware of this, and it is the principal reason why DESCRIBE *should*
be defined in terms of a portable standard. I think Common Lisp
should be commited to providing user-level support for its concepts.
I consider this as part of the criteria for being complete. By
stipulating that DESCRIBE can be written in portable CL and then
extending the language to make this true we will have satisfied one
of the requirements for making CL complete. More generally I believe
that Common Lisp should be powerful enough to implement a portable
programming environment.
Chris Eliot
∂19-May-88 1216 Common-Lisp-mailer Re: Readable Hash-Tables
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 19 May 88 12:16:37 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by ACORN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 40396; Thu 19-May-88 15:10:07 EDT
Date: Thu, 19 May 88 15:11 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: Readable Hash-Tables
To: ELIOT@cs.umass.edu
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805191539.AA07394@cayuga.cs.rochester.edu>
Message-ID: <19880519191116.1.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@CS.ROCHESTER.EDU
Reply-To: miller@CS.ROCHESTER.EDU
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: Wed, 18 May 88 12:35 EDT
From: ELIOT@cs.umass.edu
I was aware of this, and it is the principal reason why DESCRIBE *should*
be defined in terms of a portable standard. I think Common Lisp
should be commited to providing user-level support for its concepts.
I consider this as part of the criteria for being complete. By
stipulating that DESCRIBE can be written in portable CL and then
extending the language to make this true we will have satisfied one
of the requirements for making CL complete. More generally I believe
that Common Lisp should be powerful enough to implement a portable
programming environment.
Chris Eliot
I certainly concur with this. Perhaps the mythical portable code walker can
be justified as part of the standard this way too...
BTW: is it still mythical, or has anyone actually *got* one? I'd use it...
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂19-May-88 1829 Common-Lisp-mailer [portable pathname formats] visible hash tables
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 19 May 88 18:28:52 PDT
Date: Thu, 19 May 88 21:33:03 EDT
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: [portable pathname formats] visible hash tables
To: edsel!jonl@LABREA.STANFORD.EDU
cc: common-lisp@SAIL.STANFORD.EDU, Skef.Wholey@SPICE.CS.CMU.EDU
In-reply-to: Msg of Tue 17 May 88 16:22:13 PDT from Jon L White <edsel!jonl at labrea.stanford.edu>
Message-ID: <381420.880519.RWK@AI.AI.MIT.EDU>
Date: Tue, 17 May 88 16:22:13 PDT
From: Jon L White <edsel!jonl at labrea.stanford.edu>
To: Skef.Wholey at SPICE.CS.CMU.EDU
cc: common-lisp at sail.stanford.edu
Re: [portable pathname formats] visible hash tables
re: Well, just today I heard a user ask a CMU-CL implementor
about having Lucid CL on a Sun talk to CMU-CL on an RT. Among other
things, these two Lisps share the same network file system, and so
passing pathnames back and forth is a sensible thing...)
Symbolics has something like"logical pathnames"; I'm not familiar enough with
it to comment on whether or not that approach is satisfactory. Are you?
I am. Logical pathnames solve a different problem: taking a program
which contains pathnames and porting it to a different site with different
machines and directory layouts.
The problem here is rather different; a problem of naming. What is needed
is a syntax that includes an (optional) host name, and a PATHNAME-HOST
slot in pathnames. As Symbolics does, and as DEC does with their pathnames
with DECNET. (TI and LMI, too). (I don't know what DEC's CL does with this).
The syntax of the rest of the pathname is determined by the foreign
host. In Symbolics' case, since it needs to understand the syntax
(in order to do things like cross-host defaulting, etc.), it knows how
to parse each hosts' syntax locally. In DEC's case, they leave the parsing
to the remote system and pass it through uninterpreted. (Symbolics does the
same when the foreign host is of some type it never heard of, which is pretty
rare since it's heard of most things you or I would use, and is not too hard
to extend).
Logical pathnames are more useful in a networked environment, of course.
Symbolics' logical pathnames even allow you to split one logical host over
several physical hosts of various types.
∂20-May-88 2240 Common-Lisp-mailer STATELESS/SIDE-EFFECT-FREE Functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 20 May 88 22:40:34 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aq05019; 21 May 88 1:11 EDT
Received: from cs.umass.edu by RELAY.CS.NET id bg04248; 21 May 88 1:05 EDT
Date: Fri, 20 May 88 13:13 EDT
From: ELIOT@cs.umass.edu
Subject: STATELESS/SIDE-EFFECT-FREE Functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: Jon L White <edsel!jonl@labrea.stanford.EDU>
re: . . . Should "ERROR" and ...
re: . . . if a compiler can check these properties it could
also compute them. But currently it would not be allowed
to use those computed properties.
I agree with you that a compiler (and maybe even interpreter?) should do as
much consistency checking as possible. As moon implied in previous mail,
an SSC(*) should be able to determine "simpleness" mechanically. But the
danger of using that information is that it may not have been the user's
_intent_ that this function be marked as "simple" (e.g., he may want to
alter it incompatibly at a later time). An explicit proclamation (or
whatever) is the right vehicle for conveying that intent.
The previous paragraph describes the situation accurately. There seems
to be general agreement that an SSC(*) could mechanically determine
a number of properties of functions that would help a compiler
optimize code. MOON lists a veritable conspiracy of such properties
that are used by the Symbolics compiler. Most people agree that by
default a compiler should not use these properties without some
explicit proclamation (or whatever) indicating that it is OK.
(GZ seems to disagree with this.) There does seem to be a reasonable
amount of interest in making these properties known to compilers.
Using a set of ad-hoc declarations to specify these properties has
several problems. It is inevitable that these declarations will be
defined for the purpose of enabling specific optimizations.
MOON's description of the Symbolics declarations
refered to specific optimization techniques several times. The
STATELESS/SIDE-EFFECT-FREE proposal is intended to enable constant
folding.
More importantly there are subtle semantic difficulties with these
declarations. The "curious property" of functions which allocate
modifyable structures seems like a dangerous trap to me. I have
difficulty understanding the meaning and distinctions of the
Symbolics declarations. This means they have to be used slowing and
carefully, and therefore infrequently, and therefore they are not
very useful.
Even worse is the kind of bugs that can be caused. An incorrect
STATELESS declaration might be ignored in one programing environment
and eventually cause bugs only when the code is ported to another
environment, perhaps years and generations of programmers later.
I consider language features which can cause hidden
bugs of this nature dangerous, and generaly think they should
be avoided. This is why (integer 0 100) is a better type specifyer
that FIXNUM.
The only way to safely use these declarations is with a SSC(*) that
checks to verify that the function definition agrees with the
declaration. But an SSC can compute any of these properties that
it can check, so why make the programmer use the congitive
overhead required to figure out where, when and which declarations
are needed if the compiler could do it automatically? Simply
because the compiler cannot assume that that is the intended
definition of the functions involved.
From this analysis it seems very desirable to have some way to
specify that a compiler should compute and use any implementation
dependant optimization properties that it can. All of the declarations
listed by MOON are examples of things that a compiler might compute
from a function definition and use for later optimizations.
Doing so automatically would save programmers from having to learn
the meaning of all these declarations, and prevent the possible bugs
caused by their incorrect use.
So, can anyone suggest a good way to specify that a compiler
should commpute and use any implementation dependant optimizations
properties that it knows about (such as those properties listed by MOON),
preferably a mechanism with sufficient flexibility to offer both
corse and fine grained control?
One more interesting question related to what is STATELESS arises out
of noting the distinction drawn between Symbolic's declarations
[Translation: One more obscure fact that makes these declarations
harder to use correctly. :-) --CRE]
(LT:SIDE-EFFECTS LT:REDUCIBLE) and (LT:SIDE-EFFECTS LT:SIMPLE REDUCIBLE).
Is CAR STATELESS? I say yes, even though the Symbolics terminology
seems to imply that it is sensitive to side-effects. In the example:
(*) SSC -- acronym for "Sufficiently Smart Compiler"
∂24-May-88 1408 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 24 May 88 14:08:15 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191923; Tue 24-May-88 17:08:02 EDT
Date: Tue, 24 May 88 17:08 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: SIDE-EFFECT-FREE/STATELESS Functions
To: Common-Lisp@SAIL.STANFORD.EDU
In-Reply-To: <8805170055.AA02396@bhopal.lucid.com>
Message-ID: <19880524210810.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 16 May 88 17:55:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
....
One more interesting question related to what is STATELESS arises out
of noting the distinction drawn between Symbolic's declarations
(LT:SIDE-EFFECTS LT:REDUCIBLE) and (LT:SIDE-EFFECTS LT:SIMPLE REDUCIBLE).
Is CAR STATELESS? I say yes, even though the Symbolics terminology
seems to imply that it is sensitive to side-effects.
CAR is certainly sensitive to side-effects, in the sense that a side-effect
on its argument can change its result. It's true that CAR doesn't
reference any (obvious) free variables.
So, I would prefer to say that the argument to CAR can be modified by
side-effecting functions; hence a compiler must keep track not only of the
properties of the function it is compiling a call to, but also of the
potential alterations to the arguments to that function. The same analysis
applies to arrays, hash-tables, defstructs and so on, as well as to cons cells.
As I said in my earlier message, the Symbolics declarations do not
attempt to keep track of aliasing. Thus there is no distinction between
side-effects that are known to be connected with a particular object,
and side-effects in general. Aliasing can be fairly difficult to
track in Lisp, and even more so in a language extended with locatives
(which allow non-type-specific operations to access aliases).
∂24-May-88 1431 Common-Lisp-mailer replies to hash table comments
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 24 May 88 14:31:07 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 191930; Tue 24-May-88 17:30:53 EDT
Date: Tue, 24 May 88 17:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: replies to hash table comments
To: Dave.Touretzky@C.CS.CMU.EDU
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <12398139318.17.TOURETZKY@C.CS.CMU.EDU>
Message-ID: <19880524213100.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri 13 May 88 23:33:21-EDT
From: Dave.Touretzky@C.CS.CMU.EDU
To Moon: there are three reasons why DESCRIBE doesn't solve the problems
that arise in teaching beginners about hash tables:
1. In some implementations, DESCRIBE does not show the contents of a
hash table. CMU Common Lisp currently displays this regrettable (but
legal) behavior.
I think it would be better to fix the regrettable implementations than
to assume that they will always stay that way and therefore we have to
change the language to work around their flaws. If we're going to
change the language, I think it would be better to change the language
to be more specific about what DESCRIBE is for than to introduce new
substitutes for DESCRIBE on the assumption that we can never change
DESCRIBE.
2. It is a hassle for a beginner to have to type (describe my-table)
every time he wants to see what's inside his hash table.
Then he should get a better programming environment that allows this
command to be executed with less hand motion. Several exist.
And if
he's passing the hash table as an argument to a function, it would
be nice if its contents could be displayed automatically by TRACE
or by the debugger simply by setting *PRINT-HASH* to T.
Now this is an argument that I find more convincing. On the other hand,
I hate environments where TRACE dumps out such large arguments that I can't
see what's going on. I suspect your proposal can only fly if there is a
length limit and a level limit on printing of hash table contents. Of course
what's really needed is a better TRACE that shows only one line worth
of information to start, but saves the data and provides a convenient
interface for getting more detailed information when it is wanted. Hasn't
it been more than ten years since the first time I read a paper describing
something like that? It's been so long, I forget. Most Lisp implementors,
Symbolics' included, don't seem to have much imagination.
This kind
of behavior would make hash tables a first class "visible" data
structure, as easy to understand as lists and vectors.
Surely not, since hash tables have inherently more complicated structure.
3. The proposed #H notation would make it possible to read and write
hash tables from files, and to create them interactively with a single
expression rather than doing a MAKE-HASH-TABLE and a bunch of SETF's.
I don't find this convincing. #H wouldn't change what is possible in either
the file case or the interactive case, it would just make it syntactically
simpler.
Here's my problem: This is a slippery slope: today it's hash tables,
tomorrow it will be random-states, next week it will be CLOS objects,
where will it end? Also bear in mind that I hate the #A and #S syntaxes
and disable them for output whenever I can. I just don't like seeing
huge amounts of output shoved in my face. That leaves me predisposed to
oppose proposals like this one.
∂24-May-88 1524 Common-Lisp-mailer replies to hash table comments
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 May 88 15:24:01 PDT
Received: by labrea.stanford.edu; Tue, 24 May 88 15:24:11 PDT
Received: from blacksox.lucid.com by edsel id AA07662g; Tue, 24 May 88 15:14:21 PDT
Received: by blacksox id AA00323g; Tue, 24 May 88 15:18:05 pdt
Date: Tue, 24 May 88 15:18:05 pdt
From: Eric Benson <edsel!eb@labrea.stanford.edu>
Message-Id: <8805242218.AA00323@blacksox.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: Dave.Touretzky@c.cs.cmu.edu, common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Tue, 24 May 88 17:31 EDT <19880524213100.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: replies to hash table comments
Date: Tue, 24 May 88 17:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Here's my problem: This is a slippery slope: today it's hash tables,
tomorrow it will be random-states, next week it will be CLOS objects,
where will it end? Also bear in mind that I hate the #A and #S syntaxes
and disable them for output whenever I can. I just don't like seeing
huge amounts of output shoved in my face. That leaves me predisposed to
oppose proposals like this one.
Random-states have always been required to have a readable printed
representation. We're already most of the way down the slope.
∂24-May-88 1831 Common-Lisp-mailer replies to hash table comments
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 May 88 18:31:06 PDT
Received: by labrea.stanford.edu; Tue, 24 May 88 18:31:29 PDT
Received: from bhopal.lucid.com by edsel id AA08273g; Tue, 24 May 88 18:17:50 PDT
Received: by bhopal id AA07622g; Tue, 24 May 88 18:21:46 PDT
Date: Tue, 24 May 88 18:21:46 PDT
From: Jim McDonald <edsel!jlm@labrea.stanford.edu>
Message-Id: <8805250121.AA07622@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
Subject: replies to hash table comments
Date: Tue, 24 May 88 17:31 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Here's my problem: This is a slippery slope: today it's hash tables,
tomorrow it will be random-states, next week it will be CLOS objects,
where will it end? Also bear in mind that I hate the #A and #S syntaxes
and disable them for output whenever I can. I just don't like seeing
huge amounts of output shoved in my face. That leaves me predisposed to
oppose proposals like this one.
I think one of the major underrated features of lisp is that in
general you need not spend any of your programming/debugging efforts
writing code to format the objects you're manipulating.
When I had to write in Fortan or Pascal, usually the first or second
task was to identify the data structures I was going to use, and
following that to write formatting code to be used for debugging.
Then as the structures changed I would (with growing annoyance)
rewrite the formatters. I remember those days with nausea.
I also dislike huge amounts of output, but the proper mechanism is,
as you suggested, to elide the output on first showing and possibly
make it accessible in more detail later. (Otherwise, why not argue
against the default format for lists, since some are very long.)
More parameters to control the default elision would be a welcome
addition to the language/environment.
I'd really like to be able to set some global that would, for
example, make any call to print and friends immediately terminate
after 100 characters or two newlines were produced. Or terminate
when column 78 was reached. Or put all the characters in a hidden
buffer but only display the first 40 unless that buffer is explicitly
visited. Etc.
I also would like to be able to tell defstruct in some simple manner
that a particular slot is always huge and uninteresting, so print it
as #<hidden by popular request>. Ideally, I should be able to
toggle this suppression from, say, the inspector without having said
anything about it in the defstruct definition.
It just doesn't seem that hard to come up with simple solutions for
the major offenders that spew unwelcome characters.
BTW, until your message it never occurred to me there might not be a
simple way to make CLOS objects display their contents by default.
I'd call it a misfeature if you can't.
jlm
∂28-May-88 2031 Common-Lisp-mailer SIDE-EFFECT-FREE/STATELESS Functions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 28 May 88 20:31:15 PDT
Received: by labrea.stanford.edu; Sat, 28 May 88 20:31:34 PDT
Received: from bhopal.lucid.com by edsel id AA29640g; Sat, 28 May 88 20:22:09 PDT
Received: by bhopal id AA12846g; Sat, 28 May 88 20:26:21 PDT
Date: Sat, 28 May 88 20:26:21 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8805290326.AA12846@bhopal.lucid.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Tue, 24 May 88 17:08 EDT
Subject: SIDE-EFFECT-FREE/STATELESS Functions
re: As I said in my earlier message, the Symbolics declarations do not
attempt to keep track of aliasing. Thus there is no distinction between
side-effects that are known to be connected with a particular object,
and side-effects in general. Aliasing can be fairly difficult to
track in Lisp, and even more so in a language extended with locatives
(which allow non-type-specific operations to access aliases).
The issue of whether or not "CAR is sensitive to side-effects" doesn't involve
aliasing, or keeping track of particular objects. It is related to the issue
of knowing whether or not a function's arguments fall into the class of non-
modifiable objects. Numeric functions are in that class; and CAR, CDR, & etc.
aren't. The relevant part of the message that you quoted in part from is:
Date: Mon, 16 May 88 17:55:30 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
To: ELIOT@cs.umass.edu
Cc: Common-Lisp@sail.stanford.edu
Subject: SIDE-EFFECT-FREE/STATELESS Functions
. . .
By contrast, the arguments to + cannot be modified by any CLtL function,
and this is presumably what LT:SIMPLE adds to LT:REDUCIBLE for Symbolics.
[Remember my previous note about SETN in Interlisp?]. Unfortunately,
there aren't many read-only datatypes in Common Lisp.
CAR itself has no internal state, such as for example GET-UNIVERSAL-TIME has;
thus no outside events can affect the value of CAR when it is given a known
datum.
-- JonL --
∂31-May-88 1252 Common-Lisp-mailer constant folding/smashing
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 31 May 88 12:51:43 PDT
Posted-Date: Tue, 31 May 88 12:52:46 PDT
Message-Id: <8805311952.AA09512@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA09512; Tue, 31 May 88 12:52:50 PDT
To: common-lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: constant folding/smashing
Date: Tue, 31 May 88 12:52:46 PDT
Sender: goldman@vaxa.isi.edu
A flurry of messages was generated last week (on another mailing list)
by a poor common lisp programmer whose program
apparently quit working (the way he expected) due to a change in the way
the compiler dealt with quoted lists. The user was relying on two
properties of the old compiler:
i) he relied on a particular result of destructively modifying
elements of a quoted list.
ii) he relied on the compiler keeping distinct lexical occurrences of
quoted conses as distinct (non-EQ) values. The compiler had
been modified to collapse certain EQUAL quoted lists so that they
became EQ. One could no longer write
(let ((unique-value-one '(nil))
(unique-value-two '(nil)))
...)
and use EQ to distinguish two values.
The responses correctly suggested that programs which relied on the former
compiler treatment could not be expected to be portable(across common lisp
implementations or across releases). But it should be noted that the
reason for this is NOT that the "semantics of Common Lisp " makes that
clear, or that the particular vendor's lisp documentation gave any
indication that this programming practice was unsafe.
CLtL does not make it at all clear what a program is deemed to
be saying when it uses DEFCONSTANT or QUOTE. The decisions made by
compiler writers seem to be based on years of lore about how these
constructs "should" be used, rather than on any specification of what they
mean.
For example, it is plausible that if I write
(let ((c1 '((a b) (c d))))
<body>)
a compiler may "simplify" (CAAR c1) to 'a. (i.e., if the value of a
constant is a list, its CARs/CDRs, arbitrarily deep, are not supposed to
be altered.) But, as far as anything I can find WRITTEN DOWN goes, it is
just as PLAUSIBLE that if I write
(let ((c2 'X)) <body>)
I am declaring the PROPERTY-LIST of the symbol X to be unchanging, although
I doubt that anyone has yet employed that assumption in a compiler.
As correctly pointed out in one of the responses, the question of what
comprises the boundary of "constantness" of constants is distinct
from the issue of "constant collapsing". The latter is a question of
what EQUIVALENCE predicates can be imposed on lexically distinct constants
in a program. Common Lisp provides 4 universal equivalence predicates
(EQ, EQL, EQUAL, and EQUALP), as well as some type-specific equivalences
(=, char=, string=). The only reference to this issue I could find in
CLtL is a mention, under DEFCONSTANT, that an implementation may replace
lexically distinct references to a constant with EQL copies of its value
(an authorization to actually use a WEAKER equivalence than one might
expect!) This certainly leaves many other transformations in limbo as to
legitimacy.
I believe that it is NOT acceptable for these issues of program meaning to
be undefined to the extent they currently are.
Following is a cut at a proposal for clarifying these issues:
I. The meaning of a constant is based solely on the S-expression
representation of a program, not on its textual representation.
I doubt this controversial, but it does mean one can't rely on intuitions
about looking at the "source code" that appears inside a QUOTE.
[It does not matter if a constant is introduced by
'(a b #,(foo) c)
as opposed to
'(a b #,(make-myrecord :f1 1 :f2 2) c)
or
'(a b #s<myrecord :f1 1 :f2 2> c)
]
II. I would define a new equivalence predicate, SAME-BOUNDARY.
SAME-BOUNDARY would be specified for each datatype in the language. For
some, it could be defined in terms of existing equivalence predicates
(e.g., for integers, it would be EQ.) For other datatypes of the
language, certain accessors are specified to define the boundary. E.g.,
CAR/CDR for CONSes, SYMBOL-PNAME and SYMBOL-PACKAGE for SYMBOLs, all fields
for untyped defstructs, no accessors for PACKAGEs...
SAME-BOUNDARY would then be recursively defined in the "obvious" way.
[Perhaps EQUALP could be clarified to be this, or perhaps its use is
already too wide spread do do that.
There should also be a version of COPY that yields a SAME-BOUNDARY copy.]
IT IS AN ERROR for a program to modify any part of a constant to a value
that is not in the same SAME-BOUNDARY equivalence class as its original
value. An implemenation may replace a constant at any time with
a SAME-BOUNDARY copy; programs may thus rely on "pieces" of constants
only up to SAME-BOUNDARY equivalence.
An implementation may introduce declarations or proclamations that
EXTEND the set of accessors defining the boundary of constanthood.
III. Lexically distinct references to a "variable" declared by defconstant
may be replaced by SAME-BOUNDARY copies.
IV. Lexically distinct occurrences of constant expressions
-- (QUOTE x), or self-evaluating expressions -- may be replaced
by SAME-BOUNDARY copies.
V. Lexically distinct occurrences of constant expressions
may NOT be collapsed so that an equivalence predicate P holds
between them provided P is required by Common Lisp to be STRONGER
than SAME-BOUNDARY over the datatype of the expressions.
[E.g., an implementation may collapse distinct integer constants
to become EQ because
i.) SAME-BOUNDARY is defined as EQL over the integers, and
ii.) CL does not require EQ to be stronger than EQL over the integers.
]
∂01-Jun-88 1237 Common-Lisp-mailer Re: constant folding/smashing
Received: from G.BBN.COM ([8.2.0.18]) by SAIL.Stanford.EDU with TCP; 1 Jun 88 12:37:28 PDT
Date: 1 Jun 1988 15:36-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
From: NGALL@G.BBN.COM
To: goldman@VAXA.ISI.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM] 1-Jun-88 15:36:21.NGALL>
I believe there are 3 places in CLtL where "constant objects",
"constant values", and "constants in code" are discussed:
DEFCONSTANT pgs. 68-69
EQ pg. 78
QUOTE pg. 86
[Any others?]
What do these sections explicitly state about what is actually being
held constant and what can still be modified?
The DEFCONSTANT section, pgs. 68-69, explicitly allows "constant
folding" (i.e., "replac[ing] references to the name of the constant by
the value of the constant"). In this case, it is clear the the
value-cell of DEFCONSTANT's first argument (a symbol) is held
constant.
But it does not state that any of the symbol's other `components' are
held constant. E.g., Can that symbol's function-cell or plist or
home-package be modified? I believe most implementations correctly
infer the answer to be "YES".
Pgs. 68-69 also do not state whether or not the object contained in
the constant's value-cell may have its components modified (assuming
it is a composite object)? I.e., Is the value itself held constant?
I'm not sure how most implementations have decided this, but I am sure
that the DEFCONSTANT section does not authorize it (even implicitly).
In the EQ section, pg. 78, "constant collapsing" is explicitly
allowed. This is not the same thing as "constant folding" (For
a while I thought it was.) Constant folding means replacing a name by
its value (an object). Constant collapsing means replacing 2 or more
"constants in code to be compiled" that are EQUAL but not EQ with a
single one of those objects.
What is a "constant in code to be compiled?" An answer to this
question is given on pg. 78: "An object is considered to be a constant
in code to be compiled if it is a self-evaluating form or is contained
in a QUOTE form." This does not seem to allow constant collapsing of
the values of DEFCONSTANTs. I think this is an oversight, since pg.
69 allows the compiler to "replace references ... by the value of the
constant ... in order to allow further optimizations [e.g., constant
collapsing]."
So far, we have seen two types of `constant assumption/optimization'
explicity permitted: constant folding and constant collapsing.
Neither has suggested the optimization/assumption that a composite
object may be made `Read-Only'.
What about pg. 86, the section on QUOTE. Unfortunately, QUOTE muddies
the waters by using such phrases as "constant data object", "constant
object", and "constant value". It is my contention though, that these
phrases imply nothing more than the longer phrase "constant in code"
and do NOT imply that the data object itself is held to be constant.
I contend that the QUOTE special form is nothing more than a way of
providing an `anonymous DEFCONSTANT', i.e., a form that is guaranteed
to return the same (i.e, EQ) value EVERY time. For example, the
following DEFUN of FOO using QUOTE
(DEFUN FOO (N)
(IF (< -1 N (LENGTH (QUOTE (1 2 3))))
(ELT (QUOTE (1 2 3)) N)
NIL))
is semantically equivalent to the following DEFUN using an `anonymous
DEFCONSTANT'
(PROGN
(DEFCONSTANT #1=#:ANON-CONST (LIST 1 2 3))
(DEFUN FOO (N)
(IF (< -1 N (LENGTH #1#))
(ELT #1# N)
NIL)))
It is this aspect of `constant'ly returning the same (EQ) object that
is meant in the sentence on pg. 86: "[QUOTE] allows any Lisp object to
be written as a constant value in a program." It is the value of the
(QUOTE ...) form that is held constant, not the object itself. The
same (EQ) object will always be referenced, but that object may be
modified over time (if it is a composite object).
Thus, I believe that the practice of collapsing an object that is a
"constant in code to be compiled" with an EQUAL object in Read-Only
space is not authorized by CLtL, even implicitly. Moreover, I think
that the practice of collapsing an object that is a "constant in code
to be compiled" with an EQUAL object in Read-Only space is a bad idea,
since it violates the Consistency requirement between compiler and
interpreter. When learning/experimenting-with Lisp at Top-Level,
people regularly type in forms such as
(setf (first '(1 2 3)) 'a)
which won't work if quoted objects are collapsed into Read-Only
space. Also it is hard to understand why
(setf (elt '"abc" 0) #\A)
is illegal
(setf (elt '#(#\a #\b #c) 0) #\A)
is not. (You can't collapse the general array to Read-Only space since for
it to be EQUAL it must be EQ! This is why
(setf (symbol-plist 'X) '())
doesn't cause a memory violation.)
In summary, CLtL explicitly permits two constant optimizations:
folding and collapsing. But it says nothing (as far as I have found)
about what would permit an object to be put into Read-Only space,
i.e., to be made unmodifiable.
-- Nick
∂01-Jun-88 1438 Common-Lisp-mailer Re: constant folding/smashing
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 1 Jun 88 14:36:30 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by ACORN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 41778; Wed 1-Jun-88 17:15:12 EDT
Date: Wed, 1 Jun 88 17:15 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: constant folding/smashing
To: NGALL@G.BBN.COM
cc: goldman@VAXA.ISI.EDU, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM] 1-Jun-88 15:36:21.NGALL>
Message-ID: <19880601211515.2.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: 1 Jun 1988 15:36-EDT
From: NGALL@G.BBN.COM
I believe there are 3 places in CLtL where "constant objects",
"constant values", and "constants in code" are discussed:
DEFCONSTANT pgs. 68-69
EQ pg. 78
QUOTE pg. 86
[Any others?]
I think we have to be very careful about the semantics of constants and
variables. For example, does DEFUN proclaim the functional value of a symbol
is a constant? What about (compile 'mumble ...)?
I think we must break these constants down into an ontology, and consider
each class separately. Variables and Parameters (e.g. from DEFVAR and
DEFPARAMETER) are obviously different: Variables are things that may change
their values many times during a particular execution, while Parameters are
constant during a particular execution. This semantics extends into
variables and parameters vis. function calls as well, so we need not limit
ourselves to talking about program invocations.
But there seem to be some other things as well, though CL (or necessarily
any other language) break them out.
An Unknown might be defined as an object that changes at most once during a
particular execution. (A single assignment variable). Prolog variables are a
good example. (I don't necessarily think they should be in common lisp,
though they are rather hard to add given there is no way to make new
first-class objects.)
A Functional constant may be one that rarely changes between executions of
a funcion/program and never during execution. THe usual use of DEFUN covers
this: if you blow into the debugger and redefine a function, you don't
expect invocations of the function below you on the stack to be updated with
the new definition. Note that functions that are redefined during execution
are considered variables under this ontology.
A Declared constant (e.g. objects created by DEFCONSTANT) is one that Never
changes in a particular implementation. The compiler is allowed to fold
these things safely, since the user will not be expected to incrementally
patch them, without recompiling the entire system. Macros, (unfortunately in
some sense,) currently have this semantics.
A Defined constant is something that never changes BETWEEN implementations.
I.e. the value of PI, or other things some STANDARD defines. I separate this
from declared constant, because when one reads the symbol PI or E or
whatever, one beleives the reference is to this well known object (though
the implementation may have an imperfect description) rather than to some
constant the programmer has happened to name that.
I suppose if one wanted to wax ontological, one could separate two kinds of
defined constants: those that have a value as a matter of logical necessity,
i.e. their value is part of their definitions (e.g. PI) and those that
simply are not known to have changed in human experience, so we can assume
they are constant for all practical purposes (an empirical constant, like
the speed of light in a vacuum)
Now for each of these types (and a finer ontology than this may certainly be
necessary) there are the issues of when it is safe or unsafe for the
compiler to fold, and when it is just a good or a bad idea for the compiler
to fold, based on the information that will be preserved for the debugger,
allowing incremental redefinition, etc.
Now the question becomes, what sort of object is 'A? A declared constant, a
functional constant, or even a parameter? I infer that some people want to
treat it as a functional constant, which would make folding undesirable (at
least), and others a declared constant where folding would be desireable (or
at least safe and logical).
We also have to be careful in that the properties of an object may, indeed
must be treated separately. A's functional value my be a functional
constant, but it's symbol-value may be a variable or parameter. The same can
be said of any other properties of the object, except for it's printname,
which would seem to be a defined constant (the object that I write as A has
a printname of "A" is the way these sorts of atoms are defined by the
language).
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂06-Jun-88 1230 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 6 Jun 88 12:30:14 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Mon, 6 Jun 88 12:30:14 PDT
Date: Mon, 6 Jun 88 12:30:14 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <880606123014.20400214@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: test
Date: Mon, 6-JUN-1988 07:39 MST
X-VMS-Mail-To: @COMMON-LISP
Please excuse this test.
∂07-Jun-88 0058 Common-Lisp-mailer
Received: from CUNYVM.CUNY.EDU by SAIL.Stanford.EDU with TCP; 7 Jun 88 00:58:43 PDT
Received: from HDETUD1.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 1107; Tue, 07 Jun 88 03:58:52 EDT
Date: Tue, 07 Jun 88 09:57:40 MET
To: common-lisp@sail.stanford.EDU
From: ETSTMOL%HDETUD1.BITNET@CUNYVM.CUNY.EDU
Comment: CROSSNET mail via SMTP@INTERBIT
Date: 7 June 1988, 09:48:35 MET
From: Marcel Mol +31 15 783644 ETSTMOL at HDETUD1
To: COMMON-LISP at SAIL.STANFORD
Here is my (little?) question:
(... perhaps asked a hundred times :-?)
Why does Common Lisp symbols have both a function and a value cell?
Why not use one of them and use values and function as in Scheme.
Marcel
∂07-Jun-88 0722 Common-Lisp-mailer Re: little question
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 7 Jun 88 07:22:16 PDT
Date: 7 Jun 1988 10:21-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: little question
From: NGALL@G.BBN.COM
To: ETSTMOL%HDETUD1.BITNET@CUNYVM.CUNY.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM] 7-Jun-88 10:21:55.NGALL>
In-Reply-To: The message of Tue, 07 Jun 88 09:57:40 MET from ETSTMOL%HDETUD1.BITNET@cunyvm.cuny.edu
Date: Tue, 07 Jun 88 09:57:40 MET
From: ETSTMOL%HDETUD1.BITNET@cunyvm.cuny.edu
From: Marcel Mol +31 15 783644 ETSTMOL at HDETUD1
Here is my (little?) question:
(... perhaps asked a hundred times :-?)
Why does Common Lisp symbols have both a function and a value cell?
Why not use one of them and use values and function as in Scheme.
Marcel
To avoid name clashes. For example,
(defun foo (cons)
(cons (rest cons) (first cons)))
will not work in Scheme, since CONS will not have the correct value (the CONS
function). An even worse case is the following:
Programmer A writes:
(defmacro rev-cons (cons-obj)
`(cons (rest ,cons-obj) (first ,cons-obj)))
Programmer B writes:
(defun zap (cons)
(frob (rev-cons cons)))
Programmer B is surprised!
The real problem is this second example is with the semantics of
macros (which Scheme does not "officially" condone (because of the
above problem)). But since macros are such an important part of CL
and since "sanitizing" is complex, CL skirts the issue by putting
functional variables and 'normal' variables is two different namespaces.
CL progammers are used to dealing with lots of namespaces: functional,
normal variable, package, property-list, etc.
-- Nick
∂07-Jun-88 1023 Common-Lisp-mailer Re: constant folding/smashing
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 7 Jun 88 10:23:31 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA25609; Tue, 7 Jun 88 10:22:12 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA08422; Tue, 7 Jun 88 10:18:38 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA08861; Tue, 7 Jun 88 10:24:20 PDT
Date: Tue, 7 Jun 88 10:24:20 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8806071724.AA08861@clam.sun.com>
To: NGALL@G.BBN.COM, goldman@VAXA.ISI.EDU
Subject: Re: constant folding/smashing
Cc: common-lisp@SAIL.STANFORD.EDU
It was an odd sensation to me to read Nick (Gall(?))'s note.
To me, everything he said made sense, down to this paragraph:
> It is this aspect of `constant'ly returning the same (EQ) object that
> is meant in the sentence on pg. 86: "[QUOTE] allows any Lisp object to
> be written as a constant value in a program." It is the value of the
> (QUOTE ...) form that is held constant, not the object itself. The
> same (EQ) object will always be referenced, but that object may be
> modified over time (if it is a composite object).
The problem with this conclusion is that if the storage for constants
is "collapsed" together, it is impossible to know how many constants
are changing if you change a constant. A constant in someone
else's code, even system code, may be changed by your side effect.
This is an intolerable situation, so side-effects on constants
are an error.
-Cris
∂07-Jun-88 1326 Common-Lisp-mailer Re: constant folding/smashing
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 7 Jun 88 13:26:19 PDT
Posted-Date: Tue, 07 Jun 88 13:27:08 PDT
Message-Id: <8806072027.AA08564@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA08564; Tue, 7 Jun 88 13:27:21 PDT
To: COMMON-LISP@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: Re: constant folding/smashing
Cc: miller@acorn.cs.rochester.edu, cperdue@sun.com, NGALL@g.bbn.com
Date: Tue, 07 Jun 88 13:27:08 PDT
Sender: goldman@vaxa.isi.edu
Thanks for pointing out that paragraph on P.78 that explicitly
authorizing "collapsing" EQUAL constants to EQ. That at least provided
a recorded justification for the compiler's action. By the way, does
anyone know the rationale behind this authorization? Is there a big
win in implementation, or is to discourage perceived misuse of EQ-based
discriminations by programmers? It seems to me to rule out some sensible
programs (and transformations), as well as plenty of bad ones.
At any rate, as can be seen from the responses, CLtL still fails to make clear
what must be held constant about an object used as a constant in a program
(whether declared with DEFCONSTANT or appearing in a QUOTEd form).
One hypothesis of INTENT (although it does not necessarily follow from the
text) is:
Let V1 be a "constant" value. If V1 is an instance of any of the types
(listed below) for which "components" are considered in the definition
of EQUALity, then it is an ERROR for a program to modify any of those
particular components of V1. In particular, they cannot even be
changed to an EQUAL "copy" of their value.
In other words, the "boundary" of constanthood is described by the
definition of EQUAL on P.80 -- it prohibits changing:
the car or cdr of a CONS
elements of STRINGs or BIT-VECTORs
components "(host, device, and so on)" of pathnames
Within this boundary, the parts must remain EQ forever. Allocating
these parts in read-only memory is therefore permissible.
I have two questions about this:
1) is the above clear enough that an implementor knows what is allowed and
a programmer knows what he is saying?
2) Is it the right framework for an answer?
I believe that the best way to define constanthood for lisp is in terms of
the boundary used by SOME equivalence predicate. I think that within
that boundary, constants should be constrained to remain constant up to
EQness. But it doesn't follow, and I don't advocate, authorizing
an implemenation to collapse constants, OR PORTIONS THEREOF (is there an
implication that one can collapse selective parts?),
that happen to satisfy that equivalence predicate.
3) Is EQUAL what we need?
Frankly, I fail to see what is so interesting about EQUAL that makes it
the "best" equivalence predicate to use. Why not EQUALP?
I like EQUALP better, except for the fact that numbers of different type
can be EQUALP. CommonLisp is full of generic sequence operations. But
EQUAL is not one of them. It behaves quite differently for lists and
vectors, and NEVER considers a list EQUAL to a vector.
[This is the source of one's natural surprise in the example pointed out
by Nick Gall -- that
(setf (elt '#(#\a #\b #\c) 0) #\x)
must be legal.]
Because of this, a transformation that changes representations between
lists and vectors runs into oddball semantic problems wherever
EQUAL is used and, given the current semantics, wherever
constants need to be transformed.
Neil
∂07-Jun-88 1509 Common-Lisp-mailer Re: constant folding/smashing
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Jun 88 15:08:50 PDT
Received: from PEWEE.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 416067; Tue 7-Jun-88 18:09:02 EDT
Date: Tue, 7 Jun 88 18:08 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: constant folding/smashing
To: Common-Lisp@SAIL.Stanford.EDU
cc: miller@acorn.cs.rochester.edu, cperdue@sun.com, NGALL@g.bbn.com,
goldman@vaxa.isi.edu
References: <8806072027.AA08564@vaxa.isi.edu>,
<8806071724.AA08861@clam.sun.com>,
<19880601211515.2.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>,
<[G.BBN.COM] 1-Jun-88 15:36:21.NGALL>
Message-ID: <880607180851.3.KMP@PEWEE.SCRC.Symbolics.COM>
Since we're in the process of a CL overhaul, I'm not so concerned with
what's allowed as what should be.
Whether the (FOO BAR BAZ) is interpretable as read-only or not by a
compiler in
(DEFUN FOO-BAR-OR-BAZ-P (X) (MEMBER X '(FOO BAR BAZ))
is not very interesting. Indeed, even in
(DEFUN FOO-BAR-BAZ () '(FOO BAR BAZ))
I'm happy to have this return a read-only list or a list shared with
other programs because even when sharing doesn't occur, I could get
screwed by modifying the list. Consider:
(DEFUN FOO-BAR-OR-BAZ-P (X) (MEMBER X (FOO-BAR-BAZ)))
(DEFUN QUUXIFY (THING) (NCONC THING (LIST 'QUUX)))
(QUUXIFY (FOO-BAR-BAZ)) => (FOO BAR BAZ QUUX))
(QUUXIFY (FOO-BAR-BAZ)) => (FOO BAR BAZ QUUX QUUX))
HOWEVER, I am -very- concerned about the following case:
(DEFVAR *FOO-LIST* (LIST (MAKE-ARRAY 5) (MAKE-ARRAY 5)))
(DEFUN FOO-0 () '#,(NTH 0 *FOO-LIST*))
(DEFUN FOO-1 () '#,(NTH 1 *FOO-LIST*))
I want to be programming in a language that guarantees that
if I modify (NTH 0 *FOO-LIST*), then the array returned by
FOO-0 will have been modified. Moreover, I want my language
of choice to guarantee that FOO-0 and FOO-1 will not return
EQ values. In programming terms, I want the following to be
true immediately after loading the preceding three forms:
(EQ (FOO-0) (NTH 0 *FOO-LIST*)) => T
(EQ (FOO-1) (NTH 1 *FOO-LIST*)) => T
(EQ (FOO-0) (FOO-1)) => NIL
I'm concerned that under CLTL it seems to me just as valid
to get:
(EQ (FOO-0) (NTH 0 *FOO-LIST*)) => NIL
(EQ (FOO-1) (NTH 1 *FOO-LIST*)) => NIL
(EQ (FOO-0) (FOO-1)) => T
In particular, if *FOO-LIST* is a registry of arrays or structures
which is expensive to select from but which might need to be
dynamically altered, and my purpose in using #, is to allow me to
do that access once and for all at load time, but I may not wish
to commit to the unchangingness of those arrays. If QUOTE is going to
foist constancy on me, I'm screwed.
There are solutions like using closures, but they are not guaranteed
to be fast, whereas QUOTE is fast in every dialect.
There are clearly two issues involved:
- is the object evaluated or not
- is the object constant or not
Long ago, I made a rule of thumb which I've not yet found to be violated:
If you have two boolean quantities to represent,
don't try to do it with one bit.
What happens when you violate this rule is that you let a user write
just 0 or 1 and then you waste endless time arguing over whether they
really meant 00, 01, 10, or 11 when instead you should have just let
them write 00, 01, 10, or 11 and been done with it. [Friends who read
drafts of this message have jokingly dubbed this "KMP's two-bit rule".
Whatever you call it, you'll quickly see that it is quite applicable to
this problem.]
People have legitimate reasons for having quoted constants and quoted
non-constants, so should have two primitives to control the orthogonal
features of evaluation and object constancy. Then programmers could
just say what they want to say and overzealous implementors wouldn't
keep trying to second-guess them and keep them from getting work done.
I don't know what these primitives should be called, exactly, but here
are some straw-men for people to discuss:
#1: (QUOTE x) might mean X is not evaluated and is also read-only
and (IMMEDIATE x) might mean X is not evaluated but is NOT read-only.
#2: (QUOTE x) might mean X is not evaluated and NOT read-only
(CONSTANT x) might mean X is not evaluated and is also read-only.
[The observant reader will note that this is only 1.5 bits (not 2 bits) of
information. You can write either x, (QUOTE x), or (CONSTANT x) but there
is nothing that says this is a constant, evaluated expression. I didn't
propose that just because no one is asking for it. If there were a strong
need, I might have proposed that [...] means like (...) except that it
allocates the list in read-only space. Then '[A B C] would be EQUAL to
'(A B C) but '[A B C] would designate an unchanging expression and '(A B C)
would not. There have been Lisp dialects which took this approach and got
useful mileage out of it, but I'm stopping short of proposing we go that
route.]
Having a facility like this, I could presumably then do either
(CONSTANT #,X) or (IMMEDIATE #,X) as appropriate ... or I could even
still use (QUOTE #,X) -- if only I knew which of CONSTANT and IMMEDIATE
QUOTE meant!
∂08-Jun-88 0251 Common-Lisp-mailer
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 8 Jun 88 02:50:04 PDT
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03406; 8 Jun 88 10:39 BST
Received: from xenakis by mordell.maths.bath.AC.UK id aa02893;
8 Jun 88 10:37 BST
To: ETSTMOL <@cunyvm.cuny.edu:ETSTMOL@hdetud1.bitnet>
CC: common-lisp@sail.stanford.edu
In-reply-to: ETSTMOL's message of Tue, 07 Jun 88 09:57:40 MET
Date: Wed, 8 Jun 88 10:40:02 BST
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
How is progress on 1-lisp and 2-lisp? This question is one I get
asked a great deal by beginners and non soaked-in-the-culture types.
I read that a document was to be prepared by mid June on this issue.
==John
∂08-Jun-88 1043 Common-Lisp-mailer Re: constant folding/smashing
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 8 Jun 88 10:43:40 PDT
Date: 8 Jun 1988 13:42-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
From: NGALL@G.BBN.COM
To: cperdue@SUN.COM
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM] 8-Jun-88 13:42:34.NGALL>
In-Reply-To: <8806071724.AA08861@clam.sun.com>
Date: Tue, 7 Jun 88 10:24:20 PDT
From: cperdue@Sun.COM (Cris Perdue)
...
> It is this aspect of `constant'ly returning the same (EQ) object that
> is meant in the sentence on pg. 86: "[QUOTE] allows any Lisp object to
> be written as a constant value in a program." It is the value of the
> (QUOTE ...) form that is held constant, not the object itself. The
> same (EQ) object will always be referenced, but that object may be
> modified over time (if it is a composite object).
The problem with this conclusion is that if the storage for constants
is "collapsed" together, it is impossible to know how many constants
are changing if you change a constant. A constant in someone
else's code, even system code, may be changed by your side effect.
This is an intolerable situation, so side-effects on constants
are an error.
-Cris
I don't believe the following form is in error
(SETF (SYMBOL-VALUE (QUOTE X)) 1)
even though X is wrapped by (QUOTE ...) and is therefore being
"written as a constant value in a program." (See above) The reason
this ISN'T an "intolerable situation" is that in the case of a symbol,
EQUAL is the same as EQ, so you don't get UNEXPECTED side-effects.
What WOULD be intolerable would be to follow your rule ("side-effects
on constants are in error") and say that the above form is in error.
That would force people to write such things as
(SETF (SYMBOL-VALUE (INTERN "X")) 1)
My point is that in the form
(SETF (SYMBOL-VALUE (QUOTE X)) 1)
the quoted object is no more or less "constant" than in the form
(SETF (FIRST (QUOTE (A B C))) 1)
So why does QUOTE make the components of the list (1 2 3)
unmodifiable but not the components of X?
What causes the UNEXPECTED side effects in the latter form is the
folding of EQ but not EQUAL objects into one object. I am currently
thinking of a way to use DEFCONSTANT to limit such CONSTANT folding in
a CLtL compatible way (i.e., don't constant fold the values of
DEFCONSTANT).
-- Nick
∂08-Jun-88 1257 Common-Lisp-mailer Re: constant folding/smashing
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 8 Jun 88 12:57:20 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA18694; Wed, 8 Jun 88 12:54:12 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA13089; Wed, 8 Jun 88 12:50:54 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA11482; Wed, 8 Jun 88 12:56:45 PDT
Date: Wed, 8 Jun 88 12:56:45 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8806081956.AA11482@clam.sun.com>
To: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
Cc: common-lisp@SAIL.STANFORD.EDU
> I don't believe the following form is in error
> (SETF (SYMBOL-VALUE (QUOTE X)) 1)
> even though X is wrapped by (QUOTE ...) and is therefore being
> "written as a constant value in a program." (See above) The reason
> this ISN'T an "intolerable situation" is that in the case of a symbol,
> EQUAL is the same as EQ, so you don't get UNEXPECTED side-effects.
>
Agreed.
> What WOULD be intolerable would be to follow your rule ("side-effects
> on constants are in error") and say that the above form is in error.
> That would force people to write such things as
> (SETF (SYMBOL-VALUE (INTERN "X")) 1)
>
I don't think anyone intends to be proposing this. I don't.
-Cris
∂08-Jun-88 1301 Common-Lisp-mailer Call for publishable code!
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 8 Jun 88 13:01:16 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 08 JUN 88 12:59:43 PDT
Date: Wed, 8 Jun 88 11:49:09 PDT
From: Pavel.pa@Xerox.COM
Subject: Call for publishable code!
To: LispUsers↑.x@Xerox.COM, scheme@mc.lcs.mit.edu,
common-lisp@sail.stanford.edu, info-1100@sumex-aim.stanford.edu,
franz-friends@berkeley.edu, kcl@cli.com
Reply-To: Pavel.pa@Xerox.COM
Message-ID: <880608-125943-2995@Xerox>
I am the editor of the new Algorithms department of the international
newsletter/journal Lisp Pointers. The department is intended to cater to the
perceived preferences of most Lisp hackers: they'd rather write code than
articles. The articles in the department therefore fall into one or more of the
following three broad categories:
-- Annotated implementations of interesting and relevant algorithms that make
particularly good or novel use of the unique features of the Lisp family of
programming languages (e.g., closures, continuations, code as data,
polymorphism),
-- Annotated implementations of algorithms whose subject matter is the Lisp
family of languages (e.g., code analysis tools, iteration facilities, generic
arithmetic), and
-- Discussion of performance issues, benchmarking, or implementation experiences
for interesting algorithms written in or about the Lisp family of languages.
I am continually looking for ideas for appropriate articles for the department.
If you've got a nice hack you're proud of, or a particularly elegant piece of
code (you know, the kind that you call in one of your fellow hackers to see) and
you'd like to see it written up in the Algorithms department, please send it
along. What you give me doesn't have to be polished or even contain any prose;
if I agree that it's appropriate for the column, I'll work with you to put
together an article around it.
Hoping to hear from you,
Pavel Curtis
Xerox PARC/CSL
3333 Coyote Hill Rd.
Palo Alto, CA 94304
(415) 494-4455
Pavel.pa@Xerox.Com
∂08-Jun-88 1349 Common-Lisp-mailer Re: constant folding/smashing
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 8 Jun 88 13:49:33 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by ACORN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 42371; Wed 8-Jun-88 16:47:51 EDT
Date: Wed, 8 Jun 88 16:49 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: constant folding/smashing
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp@SAIL.Stanford.EDU, cperdue@sun.com, NGALL@g.bbn.com, goldman@vaxa.isi.edu
In-Reply-To: <880607180851.3.KMP@PEWEE.SCRC.Symbolics.COM>
Message-ID: <19880608204902.2.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: Tue, 7 Jun 88 18:08 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
I don't know what these primitives should be called, exactly, but here
are some straw-men for people to discuss:
#1: (QUOTE x) might mean X is not evaluated and is also read-only
and (IMMEDIATE x) might mean X is not evaluated but is NOT read-only.
#2: (QUOTE x) might mean X is not evaluated and NOT read-only
(CONSTANT x) might mean X is not evaluated and is also read-only.
How about #3: (QUOTE x) means X is not evaluated and is NOT read-only
(CONSTANT x) means X *is* evaluated and is read-only.
Thus the resulting objects from:
(CONSTANT '(A B C)) is a read-only list
'(A B C) isn't.
(constant (foo x)) evals the function and the result is read-only.
(foo x) has a non-read-only result (unless the function
foo DECLARED it to be read-only)
I don't particularly care for the [] syntax, but only because those have
been marked as explicitly reserved to the user and never to be defined by
CL.
It is still an open question, however, as to when the compiler is allowed to
take advantage of read-only objects and treat them as inline. That is,
given:
(defun foo () (constant '(a b c))
(defun mumble () (foo))
is the compiler allowed to collapse mumble into the equivalent of foo? If
so, foo cannot be incrementally recompiled, and debugging mumble gives some
non-intuitive results since the function call on foo may represent a logical
partition of the problem space. (Thus one gives up some of the advantage of
source level debugging...) So, while we have introduced a syntactic
construct to allow the user to distinguish between the eval/ro distinction,
we still have a foldability distiction that we may want to control on a
finer level than the OPTIMIZE switches will allow, and we may not be able to
just define it syntactically (though a FOLDABLE or DONT-FOLD construction
similar to the QUOTE/CONSTANT might be a step).
Here is a side example of this folding problem that declarations may not
help (due to quiroz@cs.rochester.edu):
(foo (CONSTANT '(NIL)) (CONSTANT (CONS NIL NIL)))
Now, are the first and second arguments to foo EQ or not? The point is, that
just because two objects are read-only and EQUAL does not mean that we
necessarily want to imply that they are EQ, and further that whatever is
decided we don't want different implementations doing different things here.
It seems to me that the default should be NOT eq, because if the programmer
had INTENDED eqness, they should have done something along the lines of:
(let ((bar (constant '(nil))))
(foo bar bar))
and now the EQness is explicit and obvious. The point is, there is a
distinction between ACCIDENTAL EQness and INTENTIONAL EQness. The compiler
and interpreter probably should never[1] take advantage of ACCIDENTAL
EQness. If the programmer had intended two objects to be EQ, he should have
cons'd them that way.
Another question, is defun the rough equivalent of
(setf (symbol-function x) ...) or
(setf (symbol-function x) (CONSTANT ...))
or <<very roughly>> (setf (CONSTANT (symbol-function x)) ...)
or (setf (CONSTANT (symbol-function x)) (CONSTANT ...))
i.e. to say that this symbol's functional value happens to evaluate to this
function, or this symbol's functional value happens to evaluate to this
constant function, or this symbol's functional value *will always* evaluate
to this function/ constant function. In the first two cases, we are allowing
the symbol to be associated with new functions later (e.g. incremental
compiles), and in the latter two this is prevented. The semantic difference
between the second and forth and the first and third is whether the function
may self-modify.
Currently, my opinion is along the lines of: Yes, we do need to make a
distinction as KMP suggests, because these are different things, and the
programmer should be able to represent them explicitly. However, compilers
should not take advantage of anything that has a cost in terms of debugging
or loss of incremental compiling[1]. Both *can* be maintained, of course, if
we want to carry around a list of all the references to a function that has
been folded, but the performance cost of so doing may be significant.
Further this syntactic issue still hasn't addressed a more fundamental
problem, namely the necessity of being able to control the compilers
behavior when it crosses objects that are accidentally equivalent in
some agreed upon sense (e.g. EQUAL).
[1]: (unless, of course one is doing optimize safety 0, speed 3, stupidity
3)
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂08-Jun-88 1352 Common-Lisp-mailer Re: Call for publishable code!
Received: from ACORN.CS.ROCHESTER.EDU by SAIL.Stanford.EDU with TCP; 8 Jun 88 13:52:28 PDT
Received: from DOUGHNUT.CS.ROCHESTER.EDU by ACORN.CS.ROCHESTER.EDU via CHAOS with CHAOS-MAIL id 42373; Wed 8-Jun-88 16:51:33 EDT
Date: Wed, 8 Jun 88 16:52 EDT
From: Brad Miller <miller@ACORN.CS.ROCHESTER.EDU>
Subject: Re: Call for publishable code!
To: Pavel.pa@Xerox.COM
cc: LispUsers↑.x@Xerox.COM, scheme@mc.lcs.mit.edu, common-lisp@sail.stanford.edu,
info-1100@sumex-aim.stanford.edu, franz-friends@berkeley.edu, kcl@cli.com
In-Reply-To: <880608-125943-2995@Xerox>
Message-ID: <19880608205244.4.MILLER@DOUGHNUT.CS.ROCHESTER.EDU>
Sender: miller@cs.rochester.edu
Reply-To: miller@cs.rochester.edu
Organization: University of Rochester, Department of Computer Science
Postal-address: 610 CS Building, Comp Sci Dept., U. Rochester, Rochester NY 14627
Phone: 716-275-1118
Date: Wed, 8 Jun 88 11:49:09 PDT
From: Pavel.pa@Xerox.COM
You might also try (sending your message to):
SLUG@ai.sri.com (Symbolics lisp user group)
info-ti-explorer@sumex-aim.stanford.edu
Regards,
----
Brad Miller U. Rochester Comp Sci Dept.
miller@cs.rochester.edu {...allegra!rochester!miller}
∂08-Jun-88 1408 Common-Lisp-mailer Re: constant folding/smashing
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 8 Jun 88 14:08:22 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 416610; Wed 8-Jun-88 17:07:34 EDT
Date: Wed, 8 Jun 88 17:07 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: constant folding/smashing
To: NGALL@G.BBN.COM
cc: cperdue@SUN.COM, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM] 8-Jun-88 13:42:34.NGALL>
Message-ID: <19880608210715.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 8 Jun 1988 13:42-EDT
From: NGALL@G.BBN.COM
So why does QUOTE make the components of the list (1 2 3)
unmodifiable but not the components of X?
Try thinking of it this way: Symbols don't -have- components.
There are several -associations- from symbols to other objects,
accessed by such functions as SYMBOL-VALUE and SYMBOL-PACKAGE.
Naturally the mutability of these assocations does not depend
on whether the participants in the associations are also used
as constants in one or more programs. This is the qualitative
difference between a symbol and a cons. Of course this is only
a point of view, but I think it properly reflects what Lisp
programmers expect. People are sometimes misled into thinking
that SYMBOL-PLIST and CDR are both components, because both are
implemented by the HRRZ instruction on the pdp-10, but that's
thinking in terms of the implementation rather than in terms of
the semantics.
∂09-Jun-88 0203 Common-Lisp-mailer CLOS questions, PCL version
Received: from lindy.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Jun 88 02:03:38 PDT
Received: by lindy.Stanford.EDU (4.0/4.7); Thu, 9 Jun 88 02:03:24 PDT
Received: by Forsythe.Stanford.EDU; Thu, 9 Jun 88 02:03:22 PDT
Received: by AEARN (Mailer X1.24) id 1010; Thu, 09 Jun 88 10:22:36 EDT
Date: Thu, 09 Jun 88 09:51:55 EDT
From: Hubert Hofbauer <K311770%AEARN.BITNET@Forsythe.Stanford.EDU>
Subject: CLOS questions, PCL version
To: Pavel Curtis <Pavel.pa@Xerox.COM>, Common-Lisp@Sail.Stanford.EDU
Cc: Gregor.pa@Xerox.COM, CommonLoops-Coordinator.pa@Xerox.COM
Sorry to bother you. But i did not yet get any responses from mailings
to Gregor.pa and CommonLoops-Coordinator.pa. I have seen your address on a
posting to the Scheme mailing list.
I need information on the Common Lisp Object System (CLOS) and on the
Portable Common LOOPS (PCL) implementation:
- documents on the CLOS standard in general
- information on PCL, particularly how to define meta classes
The PCL version i have is 5/22/87, delivered with DEC VAX-Lisp. Since i am
on Bitnet i do not have ftp access to the pcl directories at parcvax. I need
somebody who send new versions of the files via mail to me.
Please help me,
Hubert Hofbauer <K311770@AEARN.BITNET> or if this does not work
<K311770%AEARN.BITNET@CUNYVM.CUNY.EDU>
PS.: If Common-Lisp is a public mailing list, i would like to subscribe.
+-----------------------------------------------+-----------------------+
! Hubert Hofbauer ! K311770@AEARN.BITNET !
! Research Institute for Symbolic Computation ! RISC !
! Johannes-Kepler-Universitaet Linz ! JKU Linz !
! A-4040 Linz ! Austria / Europe !
+-----------------------------------------------+-----------------------+
∂09-Jun-88 1429 Common-Lisp-mailer Re: constant folding/smashing
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 9 Jun 88 14:29:09 PDT
Posted-Date: Thu, 09 Jun 88 14:28:50 PDT
Message-Id: <8806092128.AA23723@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA23723; Thu, 9 Jun 88 14:28:59 PDT
To: COMMON-LISP@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: Re: constant folding/smashing
Cc: KMP@stony-brook.scrc.symbolics.com, miller@acorn.cs.rochester.edu
Date: Thu, 09 Jun 88 14:28:50 PDT
Sender: goldman@vaxa.isi.edu
Kent Pitman's 1.5 bit rule is correct as far as it goes, but doesn't supply
enough bits to cover the set of declarations of "constant"ness under
discussion.
1) It says nothing about whether (portions of) the constant
can be COLLAPSED to EQness with (portions of) other constants. I am
starting to believe this may be a moot point, and that NOBODY really wants
to authorize an implementation to EQify values just because they have
been declared constant.
2) It does not address how much of READ-ONLY datum is read only. It seems
to imply that KMP does NOT like the distinction made currently between
lists and arrays. But it does not say whether, if a list is "read only"
constant, its component lists must be read-only as well.
Nor does it imply anything about other (non list or array) datatypes that
might appear QUOTEd. Just suppose I want to establish
a symbol with a couple special properties that I use as a constant --
(QUOTE
#,(let ((s (gensym)))
(setf s 0
(get s 'indicator1) 0
(get s 'indicator2) 0)))
Suppose further that I do NOT intend to change the value cell of this
symbol, or change, add, or remove any of the properties of this constant
symbol -- just read them. Should I be able to declare any of this to the
lisp implementation, so it can produce better code or allocate structure
in read-only memory? Maybe so, but certainly not by differently named
variants of QUOTE. So the only reason I can see for inventing any
variant special forms, is that there are a very few variants (but more than 1)
that cover the overwhelming majority of uses. On the other hand,
a syntax along the lines of
QUOTE object &rest declarations
leaves room for extensibility.
A comment on Brad Miller's question:
It is still an open question, however, as to when the compiler is
allowed to take advantage of read-only objects and treat them as
inline. That is, given:
(defun foo () (constant '(a b c))
(defun mumble () (foo))
is the compiler allowed to collapse mumble into the equivalent of foo?
Seems like a red herring to me. Why would the fact that foo happens to
compute a CONSTANT result influence whether or not calls on it
are allowed to be INLINEd? I don't think anyone would want foo INLINEd if
it were not explicitly declared INLINE. I see nothing in CLtL that could
be construed to authorize doing so. This is NOT the issue of constant
folding discussed in earlier messages in this series -- they have to
do with the folding of SYMBOL values for symbols declared DEFCONSTANT.
(This folding is authorized by CLtL on P. 69)
Neil
∂09-Jun-88 1439 Common-Lisp-mailer Remove from Distribution
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 9 Jun 88 14:39:09 PDT
Received: from Burger.ms by ArpaGateway.ms ; 09 JUN 88 14:31:06 PDT
Sender: "Leo_Vetter.WBST207V"@Xerox.COM
Date: 9 Jun 88 13:25:50 PDT (Thursday)
Subject: Remove from Distribution
From: "Leo_Vetter.WBST207V"@Xerox.COM
To: LispUsers↑.X@Xerox.COM, scheme@mc.lcs.mit.EDU,
common-lisp@sail.stanford.EDU, info-1100@sumex-aim.stanford.EDU,
franz-friends@berkeley.EDU, kcl@cli.COM
cc: LV.WBST207V@Xerox.COM
Reply-to: "Leo_Vetter.WBST207V"@Xerox.COM
Message-ID: <880609-143106-5374@Xerox>
Please remove me from all LISP DLs.
Thanks,
Leo Vetter
∂09-Jun-88 1510 Common-Lisp-mailer constant folding/smashing
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 9 Jun 88 15:10:13 PDT
Received: by labrea.stanford.edu; Thu, 9 Jun 88 15:09:06 PDT
Received: from bhopal.lucid.com by edsel id AA16467g; Thu, 9 Jun 88 15:00:38 PDT
Received: by bhopal id AA25338g; Thu, 9 Jun 88 14:59:16 PDT
Date: Thu, 9 Jun 88 14:59:16 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806092159.AA25338@bhopal.lucid.com>
To: NGALL@g.bbn.com
Cc: goldman@vaxa.isi.edu, cperdue@sun.com, common-lisp@sail.stanford.edu
In-Reply-To: NGALL@G.BBN.COM's message of 8 Jun 1988 13:42-EDT <[G.BBN.COM] 8-Jun-88 13:42:34.NGALL>
Subject: constant folding/smashing
re: My point is that in the form
(SETF (SYMBOL-VALUE (QUOTE X)) 1)
the quoted object is no more or less "constant" than in the form
(SETF (FIRST (QUOTE (A B C))) 1)
So why does QUOTE make the components of the list (1 2 3)
unmodifiable but not the components of X?
Because the semantic model of symbols doesn't consider them to have
modifiable components; they are "atomic". In fact, several implementations
I'm familiar do a "spaghetti-stack" lookup for the SYMBOL-VALUE function --
not a structure-component fetch. And there have been serious suggestions for
flushing the symbol-plist notion in favor of hashtables, or at least
encouraging one to use hashtable entries rather than plist entries.
The two parts of a symbol that *are* part of their semantics (as opposed
to part of their usage) are the symbol-name and the "identity" (read:
address). CL specifically makes it an error to update the symbol name;
and very little that a user can do will change the address that a symbol
is stored in -- i.e., you are guaranteed that (eq 'foo 'foo) is always true.
[Remember why EQL was introduced into the language -- (eq n n) is *not*
guaranteed to be true for numbers, so that compilers can play the pdlnum
game].
In short, I think you have confused the structure of names [in this case,
CL symbols] with their use.
Now, on the general issue of program "constants". PDP10 MacLisp would
"uniquify" constants into a read-only are at load time; other lisps do
similar things. I believe this is the intent of the few mumbling words
in CLtL about "constants". More importantly, this capability of
implementation is so important, and the hacks involved in permitting
runtime modification of constants are so un-useful, that CL should probably
confront the issue square on. ["un-useful", because the programmer's
intent is never more clear when using this hack than when using a more
approved way, such as a global parameter explicitly constructed up by
techniques like backquote or cons etc.]
Perhaps the single most damaging piece of folklore that has confused the
issue of program constants is the PDP10 MacLisp "Pun":
(defun quote fexpr (x) (car x))
This programmatic "Pun" *** must not *** be allowed to serve as a
definition for program constants. At best, something like
(defvar *constants-hashtable* (make-hash-table :test 'EQUAL))
(defun quote fexpr (x)
(let ((form (car x)))
(or (gethash *constants-hashtable* form)
(setf (gethash *constants-hashtable* form)
(purcopy form)))))
should be thought of as minimal definition. This is "minimal" in that at
least this much is required for the interpreter's definition of QUOTE to
match that of compiled code semantics. And I must stress that we all
believe this implementational style for compiled code to be necessary for
reasonable performance. [Of course, the hashtable wouldn't really be an
EQUAL table, as defined by CLtL, but something more akin to EQUALP. I
have seen the term COALESCABLEP used used. It's probably not important
just how much "collapsing" goes on.]
A word of caution on PURCOPY:
(1) PDP10 MacLisp treated symbols separately so that purcopy'ing one
didn't require moving it. [incidentally, purcopy basically means
"make me a read-only copy which is equal (or coalescablep) to
my argument"]. I have some design notes on what to do for symbols
when you can't do the PDP10 MacLisp hack; the issues are not semantic,
but merely those of efficient implementaiton of SYMBOL-FUNCTION etc.
(2) The "read only" copy needn't be be "write-protected"; of course, it
helps if it can be made so. Interlisp-D had a notion of unwriteable
strings that the microcode could detect and signal an error if you
tried to update them [well, microcode "in theory" -- maybe most
implementations simply punted to macrocode]. The point is that "it
is an error" to update such objects. There are many ways to implement
"read only" objects even if you don't want that to mean "create the
object on a write-protected page and let the operating-system give
the protection". The buzz words are "Don't confuse semantics with
implementational hacks".
-- JonL --
∂10-Jun-88 0457 Common-Lisp-mailer
Received: from CUNYVM.CUNY.EDU by SAIL.Stanford.EDU with TCP; 10 Jun 88 04:57:11 PDT
Received: from DHVRRZN1.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 8778; Fri, 10 Jun 88 07:55:58 EDT
Date: Fri, 10 Jun 88 11:07:00 MEZ
To: common-lisp@sail.stanford.edu
From: ZZZO%DHVRRZN1.BITNET@CUNYVM.CUNY.EDU
Comment: CROSSNET mail via SMTP@INTERBIT
Date: 10 June 1988, 11:06:16 MEZ
From: Wolfgang Zocher (0511) 762-3684 ZZZO at DHVRRZN1
To: COMMON-LISP at SAIL.STANFORD.EDU
Please put on the mailing list.
WZ
∂10-Jun-88 0806 Common-Lisp-mailer Re: constant folding/smashing
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 10 Jun 88 08:06:47 PDT
Date: 10 Jun 1988 11:03-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
From: NGALL@G.BBN.COM
To: edsel!jonl@LABREA.STANFORD.EDU
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]10-Jun-88 11:03:26.NGALL>
In-Reply-To: <8806092159.AA25338@bhopal.lucid.com>
Date: Thu, 9 Jun 88 14:59:16 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
re: My point is that in the form
(SETF (SYMBOL-VALUE (QUOTE X)) 1)
the quoted object is no more or less "constant" than in the form
(SETF (FIRST (QUOTE (A B C))) 1)
So why does QUOTE make the components of the list (1 2 3)
unmodifiable but not the components of X?
Because the semantic model of symbols doesn't consider them to have
modifiable components; they are "atomic". In fact, several implementations
I'm familiar do a "spaghetti-stack" lookup for the SYMBOL-VALUE function --
not a structure-component fetch. And there have been serious suggestions for
flushing the symbol-plist notion in favor of hashtables, or at least
encouraging one to use hashtable entries rather than plist entries.
From what I read in CLtL, the semantic model of symbols DOES consider
them to have modifiable components:
"Symbols have a component called the PROPERTY LIST..." pg. 24
"A Lisp symbol is a data object that has three user-visible
components [Print-name, Plist, and Package]" pg. 163
...
In short, I think you have confused the structure of names [in this case,
CL symbols] with their use.
I think you are confusing YOUR semantics of CL (which may be
widespread (Moon seems to share your view of SYMBOLs as being
componentles)s) with the semantics actually described in CLtL. I
personally find the concept of "atomic" (as opposed to composite) a
useless one in CL. I think CLtL agrees; it has virtually eliminated
the notion of "atomic". Look at the definition of ATOM on pg. 73 ("is
not a CONS"); it says nothing about the notion of atominicity. How
sensible is it to view an array as "atomic"?
And this brings up the second example of the confusion in constant
folding that no one has yet addressed: Why are lists and strings
(among others) constant folded, but not general vectors, since all of
them are composite objects? I know the answer in CLtL (two non-EQ
general vectors are not EQUAL (this is the same reason SYMBOLs aren't
folded)); what I want to know is how much sense does this distinction
make? For example, according to my understanding of the
constant-folding rule:
[1] (EQ (QUOTE #1=(gensym)) (QUOTE #1#)) => must be T
[2] (EQ (QUOTE #1=#(1 2 3)) (QUOTE #1#)) => must be T
[3] (EQ (QUOTE #1=(1 2 3)) (QUOTE #1#)) => T or NIL, wow!!!!!
How much sense does the difference in behavior between [2] and [3] make?
Now, on the general issue of program "constants". PDP10 MacLisp would
"uniquify" constants into a read-only are at load time; other lisps do
similar things. I believe this is the intent of the few mumbling words
in CLtL about "constants". More importantly, this capability of
implementation is so important, and the hacks involved in permitting
runtime modification of constants are so un-useful, that CL should probably
confront the issue square on. ["un-useful", because the programmer's
intent is never more clear when using this hack than when using a more
approved way, such as a global parameter explicitly constructed up by
techniques like backquote or cons etc.]
If this "capability of implementation" is so important, why are so few
implementations taking advantage of it? I couldn't get Symbolics CL
(which I thought WOULD do it), Vax CL, or KCL to put a "constant" into
read-only space. What implementations DO put constants in RO space?
...
(defvar *constants-hashtable* (make-hash-table :test 'EQUAL))
(defun quote fexpr (x)
(let ((form (car x)))
(or (gethash *constants-hashtable* form)
(setf (gethash *constants-hashtable* form)
(purcopy form)))))
should be thought of as minimal definition.
As KMP pointed out, you are collapsing two behaviors into one special
form. A bad idea in this case. I will have more to say on this in my
reply to him.
...
[Of course, the hashtable wouldn't really be an
EQUAL table, as defined by CLtL, but something more akin to EQUALP. I
have seen the term COALESCABLEP used used. It's probably not important
just how much "collapsing" goes on.]
I hope CLtL would clean-up EQUAL to mean "collapsable" rather than
subject the poor Lisp novice to yet another slightly-different
equality predicate.
-- Nick
∂10-Jun-88 1129 Common-Lisp-mailer Re: constant folding/smashing
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Jun 88 11:29:52 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 418025; Fri 10-Jun-88 14:28:52 EDT
Date: Fri, 10 Jun 88 14:28 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: constant folding/smashing
To: NGALL@G.BBN.COM
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <[G.BBN.COM]10-Jun-88 11:03:26.NGALL>
Message-ID: <19880610182840.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: 10 Jun 1988 11:03-EDT
From: NGALL@G.BBN.COM
....
And this brings up the second example of the confusion in constant
folding that no one has yet addressed: Why are lists and strings
(among others) constant folded, but not general vectors, since all of
them are composite objects?
What makes you think that is true? (I assume you mean "coalesced", that
is, two distinct pieces of source text resulting in a single object in the
compiled program, rather than "constant folded", which means a pure function
with constant arguments replaced by its constant result.) I don't of
anything that says that Common Lisp must treat quoted general vectors
differently from quoted strings. If some implementations do so, that's
merely an implementation.
[3] (EQ (QUOTE #1=(1 2 3)) (QUOTE #1#)) => T or NIL, wow!!!!!
I see no evidence that any interpreter or compiler is permitted to
return NIL for the above form. What you're probably thinking of
is (EQ (QUOTE #(1 2 3)) (QUOTE #(1 2 3))), which might be true or false.
Once you (or anyone else in this somewhat rambling and inconclusive
discussion) think you understand the issues above, figure out what
you think about these three forms:
(EQ (FUNCTION (LAMBDA () 1)) (FUNCTION (LAMBDA () 1)))
(EQ (FUNCTION (LAMBDA (N) (DO ((I 1 (1+ I)) (A 0 (+ A I)))
((>= I N) A))))
(FUNCTION (LAMBDA (N) (DO ((I 0 (1+ I)) (A 0 (+ A I)))
((>= I N) A)))))
(EQ (FUNCTION (LAMBDA (N) (DO ((I 1 (1+ I)) (A 0 (+ A I)))
((>= I N) A))))
(FUNCTION (LAMBDA (N) (* N (1- N) 1/2))))
Kudos to the Scheme community for elucidating this undecidable
issue some years ago.
I couldn't get Symbolics CL
(which I thought WOULD do it), Vax CL, or KCL to put a "constant" into
read-only space. What implementations DO put constants in RO space?
Try (set :foo 105) in Symbolics. It will signal a write in read only error.
That's one kind of constant.
The Symbolics compiler doesn't currently put quoted constants in
compiled functions into read-only space, because it puts the constants
and the code on the same virtual memory page and there is currently a
stupid reason why compiled functions can't normally be put into
read-only space. I believe it used to make constants read-only a few
years ago. At some point the stupid reason will be fixed and then all
constants and compiled code will be read-only (and a certain
programmer/technical manager, who I won't name but who will recognize
himself, will have to stop writing self-modifying code!).
I think you'll find that in some systems compiled code and its constants
become read-only during a system building procedure, but not when you
just call the COMPILE or LOAD functions. Nobody says read-onlyness
of constants is -required- to be enforced.
...you are collapsing two behaviors into one special
form. A bad idea in this case....
I hope CLtL would clean-up EQUAL to mean "collapsable" rather than
subject the poor Lisp novice to yet another slightly-different
equality predicate.
The above two statements don't seem to me to be based on a consistent
philosophy.
∂10-Jun-88 1225 Common-Lisp-mailer Re: constant folding/smashing
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Jun 88 12:25:48 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 418064; Fri 10-Jun-88 15:24:28 EDT
Date: Fri, 10 Jun 88 15:24 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: constant folding/smashing
To: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
cc: Cyphers@JASPER.SCRC.Symbolics.COM, NGALL@g.bbn.com, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880610191103.0.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Message-ID: <19880610192418.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 10 Jun 88 15:11 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Date: Fri, 10 Jun 88 14:28 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 10 Jun 1988 11:03-EDT
From: NGALL@G.BBN.COM
I don't of
anything that says that Common Lisp must treat quoted general vectors
differently from quoted strings.
Actually, CLtL (p. 78) is specific that an implementation only collapse
objects which are EQUAL. I personally think this is inconsistent and a
bug in CLtL.
Thanks, I somehow missed seeing that in CLtL. I agree with you that this
is inconsistent. Actually, just about anything in Common Lisp that has
anything at all to do with equality seems to be out of whack.
∂10-Jun-88 1329 Common-Lisp-mailer Re: constant folding/smashing
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 10 Jun 88 13:29:19 PDT
Date: 10 Jun 1988 16:26-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
From: NGALL@G.BBN.COM
To: Moon@SCRC-STONY-BROOK.ARPA
Cc: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]10-Jun-88 16:26:10.NGALL>
In-Reply-To: <19880610182840.2.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 10 Jun 88 14:28 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: 10 Jun 1988 11:03-EDT
From: NGALL@G.BBN.COM
....
And this brings up the second example of the confusion in constant
folding that no one has yet addressed: Why are lists and strings
(among others) constant folded, but not general vectors, since all of
them are composite objects?
What makes you think that is true? (I assume you mean "coalesced", that
is, two distinct pieces of source text resulting in a single object in the
compiled program, rather than "constant folded", which means a pure function
with constant arguments replaced by its constant result.) I don't of
Yes. I meant "collapsed" (CLtL pg. 78) not "folded".
anything that says that Common Lisp must treat quoted general vectors
differently from quoted strings. If some implementations do so, that's
merely an implementation.
I think my statement above is true based on pg. 78 (Collapsing
constants that are EQUAL) and pg. 80 (Def of EQUAL): Object X may be
collapsed with object Y iff (AND (EQUAL X Y) (NOT (EQ X Y))). This
condition can hold for strings, but NOT for general vectors, since any
EQUAL general vectors are EQ and hence are already collapsed.
[3] (EQ (QUOTE #1=(1 2 3)) (QUOTE #1#)) => T or NIL, wow!!!!!
I see no evidence that any interpreter or compiler is permitted to
return NIL for the above form.
According to the above quoted passages, the following definition for
COPY-QUOTE is semantically equivalent to QUOTE:
(defvar *copy-quote-flip-flop* nil)
(defmacro copy-quote (obj)
`(let ((obj-copy (copy ',obj)))
(if (and (equal ',obj obj-copy)
(setf *copy-quote-flip-flop* (not *copy-quote-flip-flop*)))
obj-copy
',obj)))
[Where COPY is a function that dispatches off to the appropiate copy
function (e.g., COPY-SEQ, COPY-SYMBOL, etc) if there is one, otherwise
it returns its arg.]
If you agree with this assertion, then you'll agree that an
implementation that used the above semantics for QUOTE, would return
NIL in example [3].
What you're probably thinking of
is (EQ (QUOTE #(1 2 3)) (QUOTE #(1 2 3))), which might be true or false.
Assuming that READ is non-structure-sharing, this predicate form MUST
return NIL in ALL implementations. The two vectors are not EQUAL so
they cannot be collapsed! Agreed?
Once you (or anyone else in this somewhat rambling and inconclusive
discussion) think you understand the issues above, figure out what
you think about these three forms:
(EQ (FUNCTION (LAMBDA () 1)) (FUNCTION (LAMBDA () 1)))
T or NIL
(EQ (FUNCTION (LAMBDA (N) (DO ((I 1 (1+ I)) (A 0 (+ A I)))
((>= I N) A))))
(FUNCTION (LAMBDA (N) (DO ((I 0 (1+ I)) (A 0 (+ A I)))
((>= I N) A)))))
T or NIL
(EQ (FUNCTION (LAMBDA (N) (DO ((I 1 (1+ I)) (A 0 (+ A I)))
((>= I N) A))))
(FUNCTION (LAMBDA (N) (* N (1- N) 1/2))))
T or NIL (what an optimizer! :-)
Based on my interpretation of the description of FUNCTION pgs. 87-89
But I think you're getting away from the point.
I think you'll find that in some systems compiled code and its constants
become read-only during a system building procedure, but not when you
just call the COMPILE or LOAD functions. Nobody says read-onlyness
of constants is -required- to be enforced.
You're right, nobody did say it.
...you are collapsing two behaviors into one special
form. A bad idea in this case....
I hope CLtL would clean-up EQUAL to mean "collapsable" rather than
subject the poor Lisp novice to yet another slightly-different
equality predicate.
The above two statements don't seem to me to be based on a consistent
philosophy.
You're right, I should have said
...you are collapsing two [unrelated] behaviors into one special
form. A bad idea in this case....
I hope CLtL would clean-up EQUAL to mean "collapsable" rather than
subject the poor Lisp novice to yet another [closely related]
equality predicate.
I think the confusion in the discussion demonstrates conclusively that
the current semantics of QUOTE is not well defined.
-- Nick
∂10-Jun-88 1639 Common-Lisp-mailer constant folding/smashing
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 10 Jun 88 16:39:32 PDT
Return-Path: <gls@Think.COM>
Received: from kali.think.com by Think.COM; Fri, 10 Jun 88 17:34:00 EDT
Received: by kali.think.com; Fri, 10 Jun 88 17:33:55 EDT
Date: Fri, 10 Jun 88 17:33:55 EDT
From: gls@Think.COM
Message-Id: <8806102133.AA04956@kali.think.com>
To: Moon@stony-brook.scrc.symbolics.com
Cc: DLA@jasper.scrc.symbolics.com, Cyphers@jasper.scrc.symbolics.com,
NGALL@g.bbn.com, common-lisp@sail.stanford.edu
In-Reply-To: David A. Moon's message of Fri, 10 Jun 88 15:24 EDT <19880610192418.8.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: constant folding/smashing
Date: Fri, 10 Jun 88 15:24 EDT
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
...
Actually, just about anything in Common Lisp that has
anything at all to do with equality seems to be out of whack.
For "Common Lisp", try substituting "logic", "the United States", or
"the universe".
--Guy
∂10-Jun-88 1834 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 10 Jun 88 18:34:33 PDT
Received: by labrea.stanford.edu; Fri, 10 Jun 88 18:32:21 PDT
Received: from bhopal.lucid.com by edsel id AA22886g; Fri, 10 Jun 88 18:28:36 PDT
Received: by bhopal id AA03445g; Fri, 10 Jun 88 18:27:18 PDT
Date: Fri, 10 Jun 88 18:27:18 PDT
From: Jim McDonald <edsel!jlm@labrea.stanford.edu>
Message-Id: <8806110127.AA03445@bhopal.lucid.com>
To: common-lisp@sail.stanford.edu
Subject: EQUAL
> Look at the definition of ATOM on pg. 73 ("is
> not a CONS"); it says nothing about the notion of atominicity. How
> sensible is it to view an array as "atomic"?
I think most of the confusion with EQUAL may stem from the fact that
the syntax of lisp programs is expressed with lists. When modifying
programs, writing macros, etc. it is critical to have primitives that
are sensitive to the components of your code, which effectively means
having primitives that are sensitive to the components of lists.
[Thus, to answer the question posed above, when transforming a lisp
program, arrays are atomic since they express no syntactic control
information.] There is no comparable historical reason for similar
access to the contents of strings, arrays, structures, etc.
Thus EQUAL is (in some historical sense) defined to make it easy to do
pattern matching on code. Since code traditionally becomes read-only,
this is more-or-less consistent with collapsing EQUAL structures to be
EQ. I claim that the traditional explanation for EQUAL's semantics
(that EQUAL means roughly HAVE-THE-SAME-PRINT-REPRESENTATION-P) is
actually just an observation based on this more fundamental reason.
When people try to move beyond manipulation of code, the whole basis
for the semantics of EQUAL is removed, so the result is somewhat
chaotic.
Overall, I'll argue that you must first decide what you are trying to
do (transform code, manipulate databases, build parse trees, etc.)
before you can decide what you want of your equality predicates.
Since Common Lisp presumably is not dedicated to any particular
application (except that code transformations should be supported),
I'm pessimistic that people will ever agree on simple semantics.
Also, since people in general have some esthetic sensibilities, a
fully haired roll-your-own equality predicate seems unlikely.
Since code transformation is common to almost all lisp endeavors,
EQUAL and friends should first be tested for usefulness in that
context. Then, if someone can define another similar class of
endeavors, perhaps another set of predicates can be defined to capture
the semantics needed there. So far, I have seen no coherent
description of generic data transformations, let alone one that would
warrant modification of the language.
jlm
∂10-Jun-88 2037 Common-Lisp-mailer constant folding/smashing
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 10 Jun 88 20:37:03 PDT
Received: by labrea.stanford.edu; Fri, 10 Jun 88 20:35:13 PDT
Received: from bhopal.lucid.com by edsel id AA23338g; Fri, 10 Jun 88 20:30:31 PDT
Received: by bhopal id AA03714g; Fri, 10 Jun 88 20:29:14 PDT
Date: Fri, 10 Jun 88 20:29:14 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806110329.AA03714@bhopal.lucid.com>
To: NGALL@g.bbn.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: NGALL@G.BBN.COM's message of 10 Jun 1988 11:03-EDT <[G.BBN.COM]10-Jun-88 11:03:26.NGALL>
Subject: constant folding/smashing
re: >From what I read in CLtL, the semantic model of symbols DOES consider
them to have modifiable components: ...
I think you are confusing YOUR semantics of CL (which may be
widespread (Moon seems to share your view of SYMBOLs as being
componentles)s) with the semantics actually described in CLtL.
Lisp has been around longer than Common Lisp. There are many places where
CLtL makes a stab at clarifying the generally-understood semantics, and
fails. This notion (of CLtL being "in error" at times) is not just a
"confusion" that moon and I share, but a serious topic that the X3J13
Cleanup subcommittee is addressing.
Lest anyone get the wrong impression from what I've just said, let me
add that I find CLtL one of the truly impressive documents in Computer
Science. I can hardly praise it highly enough. It just isn't 100%
perfect.
re: If this "capability of implementation" [read-only constants] is so
important, why are so few implementations taking advantage of it?
. . . What implementations DO put constants in RO space?
Lucid Common Lisp, for one. Because of efficiency questions, you
will not actually have the "read-only" constant put into a write-protected
area of memory until after a subsequent "DISKSAVE". On Unix hosts,
this typically means re-ordering the image so that all the constants
and other read-only stuff are in the text segment. Maybe some of the
other implementations you tried and failed on do the same thing, and
you just didn't look at them after the corresponding "world dump".
re: I hope CLtL would clean-up EQUAL to mean "collapsable" rather than
subject the poor Lisp novice to yet another slightly-different
equality predicate.
Thank you for your opinion. I used the word COALESCABLEP rather than
"collapsable"; I should hope that whatever notion is acceptable to the
X3J13 committee will imply "substitution of one similar, but non-EQ, datum
for another" rather than "utter collapse" of a particular structure.
-- JonL --
∂10-Jun-88 2316 Common-Lisp-mailer constant folding/smashing
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 10 Jun 88 23:16:15 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab13411; 11 Jun 88 2:11 EDT
Received: from cs.umass.edu by RELAY.CS.NET id av06082; 11 Jun 88 2:03 EDT
Date: Fri, 10 Jun 88 11:32 EDT
From: ELIOT@cs.umass.edu
Subject: constant folding/smashing
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: in%"common-lisp@sail.stanford.EDU"
What about constant hash-tables? No variety of QUOTE can build
a constant hash table because there is no notation for them.
(I don't count #.(make-hash-table...) because it's so gross.)
This suggests that something like the 'purcopy' function is still
needed. However, should this be recursive in the case of hash tables?
Certainly the KEYS of ANY hash table must be thought of as constants,
because otherwise the table can become inconsistent. But I can
think of situations both where the values should also be constants
(if the table is) and where the valueshould not be constants.
Making 'pucopy' non-recursive is fine for large data structures,
like arrays, structures, strings etc., but I think most people
feel that CONSes in list structure should be handled in one fell
swoop. Perhaps a 'pucopy' function should accept a data argument
and an arbitrary number of type specifiers, indicating the
data types to recurse through.
In general I like the idea of quoted constants being read-only,
because it ensures that the semantics of a function at run-time
are apparent from its textual representation as code. If constants
are not read-only then:
(defun foo ()
'(a b c))
Really means
(defun foo ()
G00047)
(setq G00047 '(a b c))
On the other hand, I think it would be consistent to define BACKQUOTE
so that it always makes a fresh copy of its entire argument. This
is reasonable, since BACKQUOTE already has to copy its argument
down to the last comma. Die-hards who really want to avoid the
final CONSing in a BACKQUOTE could use ,'(...) to insert un-copied
structure.
∂11-Jun-88 1024 RPG
∂11-Jun-88 0040 @RELAY.CS.NET:ito%ito.aoba.tohoku.junet@UTOKYO-RELAY.CSNET
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 11 Jun 88 00:40:00 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab13961; 11 Jun 88 3:32 EDT
Received: from utokyo-relay by RELAY.CS.NET id ad06539; 11 Jun 88 3:26 EDT
Received: by ccut.cc.u-tokyo.junet (5.51/6.3Junet-1.0/CSNET-JUNET)
id AA29153; Sat, 11 Jun 88 14:28:00 JST
Received: by nttlab.ntt.jp (4.12/6.2NTT.h) with TCP; Sat, 11 Jun 88 13:42:29 jst
Received: by aoba.aoba.tohoku.junet (4.12/6.3Junet-1.0); Sat, 11 Jun 88 12:45:19 jst
Received: by ito.aoba.tohoku.junet (4.12/6.3Junet-1.0)
id AA00215; Sat, 11 Jun 88 12:36:19 jst
Date: Sat, 11 Jun 88 12:36:19 jst
From: Takayasu ITO <ito%ito.aoba.tohoku.junet@UTOKYO-RELAY.CSNET>
Return-Path: <ito@ito.aoba.tohoku.junet>
Message-Id: <8806110336.AA00215@ito.aoba.tohoku.junet>
To: x3j13-request%sail.stanford.edu%RELAY.CS.NET%u-tokyo.junet@UTOKYO-RELAY.CSNET
Subject: X3J13 mailing matter
I received a physical letter from Bob Mathis but I haven't received any
electronic mail.
Would you enter my mail address into your mailing list?
I also wish to be in the physical mail distribution list since e-mail is not
reliable sometimes.
Please send the bill for the membership and mailing to me.
Sincerely,
Takayasu Ito
e-mail address: ito@aoba.tohoku.junet
physical mail address: Professor Takayasu Ito
Department of Information Engineering
School of Engineering
Tohoku University
Sendai, JAPAN 980
(P.S.) I cannot attend Boston meeting,since I have just returned from Greece.
∂11-Jun-88 1738 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 11 Jun 88 17:37:55 PDT
Received: by labrea.stanford.edu; Sat, 11 Jun 88 17:36:49 PDT
Received: from bhopal.lucid.com by edsel id AA26883g; Sat, 11 Jun 88 17:33:22 PDT
Received: by bhopal id AA05974g; Sat, 11 Jun 88 17:32:08 PDT
Date: Sat, 11 Jun 88 17:32:08 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806120032.AA05974@bhopal.lucid.com>
To: edsel!jlm@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Jim McDonald's message of Fri, 10 Jun 88 18:27:18 PDT <8806110127.AA03445@bhopal.lucid.com>
Subject: EQUAL
I like you analysis, and think it explains very well why EQUAL has the
peculiar semantics that it now has.
How would you feel about extending EQUAL to descend defsturct structures
and T-type arrays? it wouldn't mess up its utility for its original
purpose, and would satisfy an enormous number of Lisp users. Of course,
EQUAL type hashtables would work with this new definition.
As we have often said, EQUALP went a little bit too far -- because of
ignoring representation type on numbers and character case in strings.
I think there should be an EQUALP type hashtable as long as there's
an EQUALP function; but a satisfactorily extended EQUAL function might
make it less of pressing issue.
-- JonL --
∂11-Jun-88 1755 Common-Lisp-mailer constant folding/smashing
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 11 Jun 88 17:55:17 PDT
Received: by labrea.stanford.edu; Sat, 11 Jun 88 17:54:10 PDT
Received: from bhopal.lucid.com by edsel id AA26900g; Sat, 11 Jun 88 17:48:01 PDT
Received: by bhopal id AA06005g; Sat, 11 Jun 88 17:46:49 PDT
Date: Sat, 11 Jun 88 17:46:49 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806120046.AA06005@bhopal.lucid.com>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of Fri, 10 Jun 88 11:32 EDT <8806110719.AA23994@edsel.lucid.com>
Subject: constant folding/smashing
re: What about constant hash-tables? No variety of QUOTE can build
a constant hash table because there is no notation for them.
(I don't count #.(make-hash-table...) because it's so gross.)
Lucid's "Re-Targetable" compiler is table driven; the tables are ordinary
CL hashtables. In recent images, they are stored in read-only memory, since
all the key entries are symbols, and since they change very rarely (such
as when someone is debugging the compiler). A "lazy migration" scheme
ensures that they become writeable upon demand.
There is a proposal before X3J13 now (presented by Dave Touretzky) to
give a printable representation to hashtables. If a sufficiently powerful
version of it is adopted, then it should be possible to use QUOTE to
reference a constant hashtable.
I don't think the techniques that Lucid uses to build read-only tables
are exported to the end-user; but it certainly is possible to reference
"constant" hashtables using the "gross" #. notation, and have such code
be compiled and loaded correctly.
-- JonL --
∂11-Jun-88 1836 Common-Lisp-mailer constant folding/smashing (constant hash tables)
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 11 Jun 88 18:35:23 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA07785; Sat, 11 Jun 88 19:34:03 MDT
From: sandra@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8806120134.AA07785@cs.utah.edu>
Date: Sat, 11 Jun 88 19:34:01 MDT
Subject: constant folding/smashing (constant hash tables)
To: common-lisp@sail.stanford.edu
Cc: edsel!jonl@labrea.stanford.edu, eliot@cs.umass.edu
> From: edsel!jonl@labrea.stanford.edu (Jon L White)
> Subject: constant folding/smashing
>
> re: What about constant hash-tables? No variety of QUOTE can build
> a constant hash table because there is no notation for them.
> (I don't count #.(make-hash-table...) because it's so gross.)
>
> There is a proposal before X3J13 now (presented by Dave Touretzky) to
> give a printable representation to hashtables. If a sufficiently powerful
> version of it is adopted, then it should be possible to use QUOTE to
> reference a constant hashtable.
There is already a way to make a constant hashtable with QUOTE. Try:
(defmacro make-a-constant-hash-table ()
`(quote ,(make-hash-table ...)))
This same trick can also be used to make "constants" out of other kinds
of weird objects, like packages or streams.
-Sandra
-------
∂12-Jun-88 2212 Common-Lisp-mailer Backquote Constants
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 Jun 88 22:12:38 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac01479; 13 Jun 88 1:07 EDT
Received: from cs.umass.edu by RELAY.CS.NET id ae19893; 13 Jun 88 1:00 EDT
Date: Sun, 12 Jun 88 13:08 EDT
From: ELIOT@cs.umass.edu
Subject: Backquote Constants
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
>From: IN%"sandra@cs.utah.EDU" "Sandra J Loosemore" 12-JUN-1988 02:41
>
>> From: edsel!jonl@labrea.stanford.edu (Jon L White)
>>
>> re: What about constant hash-tables? No variety of QUOTE can build
>> a constant hash table because there is no notation for them.
>> (I don't count #.(make-hash-table...) because it's so gross.)
>>
>> There is a proposal before X3J13 now (presented by Dave Touretzky) to
>> give a printable representation to hashtables. If a sufficiently powerful
>> version of it is adopted, then it should be possible to use QUOTE to
>> reference a constant hashtable.
>
>There is already a way to make a constant hashtable with QUOTE. Try:
>
> (defmacro make-a-constant-hash-table ()
> `(quote ,(make-hash-table ...)))
>
>This same trick can also be used to make "constants" out of other kinds
>of weird objects, like packages or streams.
>
>-Sandra
>-------
At first I thought this was crazy, since this implies that backquote
copies data inside a comma and I didn't think backquote was allowed
to do this. However, Cltl P.350 says:
"...an implementation is free to interpret a backquoted form as any form
that,... is EQUAL to the result implied by the above definition."
(My caps.)
So, you are right, and CltL is (in my opinion) wrong. As CltL says
on page 351 "There is no good reason why copy-list should be
performed, but it is not prohibited." If there is
no good reason why copying should be performed, then it *should* be
prohibited. I don't know of any implementation which gratuitously
copies extra structure in backquoted forms and I consider the
possibility to be grossly unintuitive. In fact, I think some code
I wrote a few years ago is probably "in error" because of this
very obscure ambiguity. I strongly believe that the intuitive way
for backquote to work is to directly incorporate the results
of comma evaluation into the result without modification,
exactly as if the corresponding set of calls to CONS had been
coded directly. Unless there is a good reason for the ambiguity in
the definition it must be considered a bad definition.
Perhaps the ambiguity in the definition is an attempt to allow
for some of the read-only/collapsing optimizations that are being
discussed. If so, then as KMP said this is an attempt to combine
two kinds of functionality into a single construct. I consider
backquote to be a *shorthand* data construction primitive. Anything
produced by backquote can, more generally, be produced by a combination
of CONS, VECTOR, QUOTE and other functions.
If we need a way to construct read-only data structure (it would be
nice) then there should be a *general* way to do so, corresponding to
the general use of CONS, VECTOR and QUOTE to produce data structures.
It would be unfortunate to introduce a new way to manipulate data
without making it general.
As an aside, the description of the difference between ,@ and ,.
seems to be incoherent. The syntax ,. indicates that it is
permissible to destroy (i.e. incorporate?) the list produced
by the following form. However, the example on p.351 indicates
that it is permissible to incorporate the list produced by the ,@ form
also. I fail to see how these differ.
∂12-Jun-88 2311 Common-Lisp-mailer EQUAL
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 12 Jun 88 23:05:19 PDT
Date: Mon, 13 Jun 88 02:05:15 EDT
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: EQUAL
To: edsel!jlm@LABREA.STANFORD.EDU
cc: common-lisp@SAIL.STANFORD.EDU
In-reply-to: Msg of Fri 10 Jun 88 18:27:18 PDT from Jim McDonald <edsel!jlm at labrea.stanford.edu>
Message-ID: <396357.880613.RWK@AI.AI.MIT.EDU>
Date: Fri, 10 Jun 88 18:27:18 PDT
From: Jim McDonald <edsel!jlm at labrea.stanford.edu>
Thus EQUAL is (in some historical sense) defined to make it easy to do
pattern matching on code. Since code traditionally becomes read-only,
this is more-or-less consistent with collapsing EQUAL structures to be
EQ. I claim that the traditional explanation for EQUAL's semantics
(that EQUAL means roughly HAVE-THE-SAME-PRINT-REPRESENTATION-P) is
actually just an observation based on this more fundamental reason.
When people try to move beyond manipulation of code, the whole basis
for the semantics of EQUAL is removed, so the result is somewhat
chaotic.
While this all sounds very nice, I'm afraid you're engaging in
a bit of historical revisionism.
Originally, LISP didn't have all these nice hairy datatypes.
Those of us who were there (Not me!) can tell about what McCarthy
wrought, but I know I've seen Lisp's without arrays at all. I know
people have been using EQUAL to compare data more often than to compare
code for a very long time.
In fact, EQUAL doesn't work on code, plain and simple. To compare
code, you must first recognize that it is not computable to compare
two functions which contain quoted data, unless that quoted data is
EQ. You also have to place constraints on macros to not be pathological
(i.e. sick).
To illustrate a couple examples:
(defvar *call-registry* (make-hash-table :test 'eq))
(defvar *macro-registry* (make-hash-table :test 'eq))
(defun register-macro-marker (marker)
(let ((marker (gethash *macro-registry* marker)))
(unless marker
(setf marker `',(gensym))
(setf (gethash *macro-registry* marker) marker))
marker))
(defun register-call (marker result)
(push result (gethash *call-registry* marker)))
(defmacro register (&whole marker)
`(register-call ,(register-macro-marker marker) ,(second marker)))
(defun confound (flag)
(if flag (register '(MARKER)) (register '(MARKER))))
Are the two branches of the IF equivalent? EQUAL says yes.
I leave it as an exercise for the reader to count how many
ways and on how many levels those two branches differ.
[I apologize in advance for any spazzes in the code; I have to
type it in by hand; I don't have any way of transfering files
to or from arpanetland for testing, and editing directly on ITS
doesn't work well for me either].
In short, what EQUAL is good for is comparing "old-style" data
(that is, data structures like are used in such venerable programs
as Macsyma -- and there are some exceptions there, too).
I do think it would be reasonable to define an extremely limited set
of new predicates. I would suggest limiting it to two new ones that
do the two pieces of EQUALP -- descend other structures, and merge
case in strings and characters.
I would strongly discourage any attempt to "solve the problem of
comparisons", on the grounds that it will require more hair, additions
to the language, and discussion than it could possibly be worth.
∂12-Jun-88 2332 Common-Lisp-mailer constant folding/smashing
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 12 Jun 88 23:31:34 PDT
Date: Mon, 13 Jun 88 02:31:18 EDT
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
Subject: constant folding/smashing
To: edsel!jonl@LABREA.STANFORD.EDU
cc: common-lisp@SAIL.STANFORD.EDU, goldman@VAXA.ISI.EDU,
cperdue@SUN.COM, NGALL@G.BBN.COM
In-reply-to: Msg of Thu 9 Jun 88 14:59:16 PDT from Jon L White <edsel!jonl at labrea.stanford.edu>
Message-ID: <396377.880613.RWK@AI.AI.MIT.EDU>
Date: Thu, 9 Jun 88 14:59:16 PDT
From: Jon L White <edsel!jonl at labrea.stanford.edu>
To: NGALL at g.bbn.com
cc: goldman at vaxa.isi.edu, cperdue at sun.com,
common-lisp at sail.stanford.edu
Re: constant folding/smashing
re: My point is that in the form
(SETF (SYMBOL-VALUE (QUOTE X)) 1)
the quoted object is no more or less "constant" than in the form
(SETF (FIRST (QUOTE (A B C))) 1)
So why does QUOTE make the components of the list (1 2 3)
unmodifiable but not the components of X?
Because the semantic model of symbols doesn't consider them to have
modifiable components; they are "atomic". In fact, several implementations
Wrong reason. (As has been pointed out in other discussion).
(SETF (SYMBOL-VALUE 'X) 1)
is the same as
(SETQ X 1), for X being special.
The X in either piece of code is a REFERENCE to a non-constant object,
shared between occurrances of read. It is a PUBLIC structure published
by INTERN. Modifications to its value cell are modifications to the global
variable environment. They're already EQified as much as makes sense.
The list structure in '(A B C) is a private structure not obtainable
by any other call to READ. EQification makes sense.
Where this breaks down, of course, is macros. Symbols, obviously, are
always (potentially) a shared resource (if interned). Lists are provably
private if they came from READ, but not from macroexpansion. As you point
out, EQification is part of the semantics of QUOTE. To clean this up, we
have to be more explicit in the semantics of QUOTE. In fact, let me assert
that one special form cannot accomplish all the variations of what behaviour
you'd like to see. You'd like to be able to establish explicit control
over what things are shared & read-only in a datastructure, presumably by
providing your own function. QUOTE should follow simple rules (the rules
it now follows, I claim, because it discourages self-modifying programs).
∂13-Jun-88 1004 Common-Lisp-mailer EQUAL
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 13 Jun 88 10:04:32 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA22912; Mon, 13 Jun 88 10:02:01 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA06262; Mon, 13 Jun 88 09:58:29 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA07423; Mon, 13 Jun 88 10:04:00 PDT
Date: Mon, 13 Jun 88 10:04:00 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8806131704.AA07423@lukasiewicz.sun.com>
To: edsel!jlm@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Jim McDonald's message of Fri, 10 Jun 88 18:27:18 PDT <8806110127.AA03445@bhopal.lucid.com>
Subject: EQUAL
Date: Fri, 10 Jun 88 18:27:18 PDT
From: Jim McDonald <edsel!jlm@labrea.stanford.edu>
...
Thus EQUAL is (in some historical sense) defined to make it easy to do
pattern matching on code. Since code traditionally becomes read-only,
this is more-or-less consistent with collapsing EQUAL structures to be
EQ. I claim that the traditional explanation for EQUAL's semantics
(that EQUAL means roughly HAVE-THE-SAME-PRINT-REPRESENTATION-P) is
actually just an observation based on this more fundamental reason.
...
Also, since people in general have some esthetic sensibilities, a
fully haired roll-your-own equality predicate seems unlikely.
...
jlm
Date: Sat, 11 Jun 88 17:32:08 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
I like you analysis, and think it explains very well why EQUAL has the
peculiar semantics that it now has.
How would you feel about extending EQUAL to descend defsturct structures
and T-type arrays? it wouldn't mess up its utility for its original
purpose, and would satisfy an enormous number of Lisp users. Of course,
EQUAL type hashtables would work with this new definition.
...
-- JonL --
To add fuel to the fire: Since EQUAL bears an observable relationship
to READ and WRITE, there's an obvious way to supply a "fully haired
roll-your-own equality predicate". Add, to EQUAL, keyword arguments
analogous to WRITE, for controlling these debatable behaviors.
E.g., the people who want to compare array substructure would
use a call like this:
(EQUAL X Y :ARRAY T)
Comparison of structures would be controlled by the :STRUCTURE
keyword. Hash tables could be handled similarly, especially
if hash-table printing is ever made standard. Perhaps case
sensitivity in strings could be controlled by :CASE.
Something should be done for numbers too.
I hope there's no call for the analogous special variables,
e.g., *EQUAL-ARRAY*!
We might go further, by allowing the argument to :ARRAY or
:STRUCTURE to be an equality predicate instead of a boolean.
This would allow somewhat better control over, e.g., which
types of structure were to be opened up for comparison.
(A DEFSTRUCT option controlling equality behavior would be
much preferable, for reasons of modularity.)
-- John
∂13-Jun-88 1152 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 13 Jun 88 11:52:41 PDT
Received: by labrea.stanford.edu; Mon, 13 Jun 88 11:50:44 PDT
Received: from bhopal.lucid.com by edsel id AA02227g; Mon, 13 Jun 88 11:37:35 PDT
Received: by bhopal id AA10559g; Mon, 13 Jun 88 11:36:30 PDT
Date: Mon, 13 Jun 88 11:36:30 PDT
From: Jim McDonald <edsel!jlm@labrea.stanford.edu>
Message-Id: <8806131836.AA10559@bhopal.lucid.com>
To: RWK@ai.ai.mit.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: "Robert W. Kerns"'s message of Mon, 13 Jun 88 02:05:15 EDT <396357.880613.RWK@AI.AI.MIT.EDU>
Subject: EQUAL
While this all sounds very nice, I'm afraid you're engaging in
a bit of historical revisionism.
After hitting <return> I had second thoughts along those lines, but
third thoughts removed them. (Now I'm afraid to hit return again. :-)
Originally, LISP didn't have all these nice hairy datatypes.
Those of us who were there (Not me!) can tell about what McCarthy
wrought, but I know I've seen Lisp's without arrays at all.
No fair. That's an argument for my position.
I know
people have been using EQUAL to compare data more often than to compare
code for a very long time.
One of the tenants of evolution is that rather small advantages can drive
natural selection. If EQUAL and EQUAL' are of comparable utility for
comparing data, but EQUAL is much better for code, then EQUAL will
prevail, even if 99% of the comparisons are for data.
In fact, EQUAL doesn't work on code, plain and simple. To compare
code, you must first recognize that it is not computable to compare
two functions which contain quoted data, unless that quoted data is
EQ. You also have to place constraints on macros to not be pathological
(i.e. sick).
But EQUAL *does* work on code. E.g., I might have a rewrite system in
my compiler that makes all sorts of modifications and then checks to
see if the result is EQUAL. If not, it goes around again. Since the
code analysis is using CAR, CDR, CONS, LIST, etc. and never copying
arrays or other objects, EQUAL is precisely the right test.
Textbook arguments and pathological examples miss the historical point
I was making. My sense is that the early implementers were pragmatic
enough not to fall into the trap of avoiding something useful because
it was not (and could never be) perfect.
In short, what EQUAL is good for is comparing "old-style" data
(that is, data structures like are used in such venerable programs
as Macsyma -- and there are some exceptions there, too).
I would include "old-style" and most "new-style" code. Another way of
phrasing my argument is that "old-style" code and data were so similar
as to blur the uses of EQUAL. "New-style" data has evolved more, so
discrepencies are emerging between the uses.
I do think it would be reasonable to define an extremely limited set
of new predicates. I would suggest limiting it to two new ones that
do the two pieces of EQUALP -- descend other structures, and merge
case in strings and characters.
I agree with the focus, but probably not the details.
I would strongly discourage any attempt to "solve the problem of
comparisons", on the grounds that it will require more hair, additions
to the language, and discussion than it could possibly be worth.
Agreed!
jlm
∂13-Jun-88 1248 Common-Lisp-mailer constant folding/smashing
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Jun 88 12:48:29 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 419009; Mon 13-Jun-88 15:47:15 EDT
Date: Mon, 13 Jun 88 15:47 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: constant folding/smashing
To: ELIOT@cs.umass.edu
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: The message of 10 Jun 88 11:32 EDT from ELIOT@cs.umass.edu
Message-ID: <19880613194703.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Fri, 10 Jun 88 11:32 EDT
From: ELIOT@cs.umass.edu
(I don't count #.(make-hash-table...) because it's so gross.)
I object to the characterization of doing something through the normal
syntax, instead of inventing a special weird syntax that people have
to learn as a special case, as "gross."
∂13-Jun-88 1439 Common-Lisp-mailer Re: constant folding/smashing
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 13 Jun 88 14:38:56 PDT
Received: from Burger.ms by ArpaGateway.ms ; 13 JUN 88 14:20:47 PDT
Sender: "David_Snyder.Wbst208"@Xerox.COM
Date: 13 Jun 88 07:22:28 PDT (Monday)
Subject: Re: constant folding/smashing
From: "David_Snyder.Wbst208"@Xerox.COM
To: gls@Think.COM
cc: Moon@stony-brook.scrc.symbolics.COM, DLA@jasper.scrc.symbolics.COM,
Cyphers@jasper.scrc.symbolics.COM, NGALL@g.bbn.COM,
common-lisp@sail.stanford.EDU
In-Reply-to: gls%Think:COM:Xerox's message of 10 Jun 88 19:28
Message-ID: <880613-142047-9689@Xerox>
Will the substitution preserve EQness?
∂13-Jun-88 1551 Common-Lisp-mailer Re: constant folding/smashing
Received: from G.BBN.COM by SAIL.Stanford.EDU with TCP; 13 Jun 88 15:51:32 PDT
Date: 13 Jun 1988 18:50-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: constant folding/smashing
From: NGALL@G.BBN.COM
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]13-Jun-88 18:50:37.NGALL>
In-Reply-To: The message of Fri, 10 Jun 88 11:32 EDT from ELIOT@cs.umass.edu
Date: Fri, 10 Jun 88 11:32 EDT
From: ELIOT@cs.umass.edu
What about constant hash-tables? No variety of QUOTE can build
a constant hash table because there is no notation for them.
(I don't count #.(make-hash-table...) because it's so gross.)
Once again, I will state that the problem is not notation. QUOTE
cannot cons its argument into RO-space because the argument has ALREADY
BEEN CONSED. All QUOTE can do it to cons in RO-space an EQUAL COPY of
its argument and return that copy. But there is NO SUCH THING as an
EQUAL "COPY" of a hashtable. It doesn't matter that its gross, it
just won't work.
In general I like the idea of quoted constants being read-only,
because it ensures that the semantics of a function at run-time
are apparent from its textual representation as code. If constants
are not read-only then:
(defun foo ()
'(a b c))
Really means
(defun foo ()
G00047)
(setq G00047 '(a b c))
Funny, this is the semantics that most Lisper's have as their initial
mental model (and I assume find the most intuitive). It is also the
semantics of all (?) CL interpreters. QUOTE MUST have the same
behavior in the compiler and the interpreter. To do otherwise is to
introduce a compiler/interpreter incompatibility as confusing and
error-prone as the SPECIAL variable incompatibility used to be. Agreed?
If you want to suggest that the interpreter should be changed to make
QUOTE return a RO-EQUAL-copy of its arg when possible*** (as I think JonL
may have been suggesting?), then consider what a pain it will cause at
the top-level:
> (setf foo '(1 2 3))
(1 2 3)
> (push 0 foo)
>>>>> Error ...
Instead, you'll have to do:
> (setf foo (list 1 2 3))
(1 2 3)
> (push 0 foo)
(0 1 2 3)
A lot of Lisp textbooks will have to be rewritten!
-- Nick
*** Actually, the interpreter's handling of self-evaluating forms will
have to be changed too.
∂14-Jun-88 1133 Common-Lisp-mailer (macro . atom)
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 14 Jun 88 11:33:05 PDT
Posted-Date: Tue, 14 Jun 88 11:32:48 PDT
Message-Id: <8806141832.AA16045@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA16045; Tue, 14 Jun 88 11:32:51 PDT
To: common-lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: (macro . atom)
Date: Tue, 14 Jun 88 11:32:48 PDT
Sender: goldman@vaxa.isi.edu
Consider the following macro definitions:
(defmacro MACW (&whole w) `(- ,(cdr w)))
(defmacro MACR (&rest r) `(- ,r ))
and uses of them:
(a) (MACW . 1)
(b) (MACR . 1)
I tried these on 3 CL implementations, with the following results:
1) Implementation 1 accepted both forms, binding w to (MACW . 1) in (a)
and r to T in (b)
2) Implementation 2 treated case (a) the same as implementation 1, but
rejected (b), saying that T was not a list.
3) Implementation 3 rejected both cases, saying that T was not a list.
Interestingly, it gladly accepted both forms as arguments to
MACROEXPAND-1, binding w and r the same as implementation 1.
Question#1 -- what is the allowable behavior of an implementation in
the case of (MACR . T)? Are all 3 valid?
Question#2 -- what about the case of (MACW . T)? Should my MACW code
be portable, or am I just lucky that 2 of these implementations let me
get away with it?
----------------------------------------------------------------
Relevant sections of CLtL:
On P.54, it states that only certain forms are "meaningful":
self-evaluating forms, symbols, and "lists". If (MACW . T) and (MACR . T)
are "meaningful", they must be lists.
On Pp. 26-27, we have definitions of LIST and DOTTED LIST. (My examples
are dotted lists). In the middle of P.27 is a rather odd paragraph. First
it seems to say that uses of the term LIST in the book include dotted
lists, and the the term "true list" will be used if dotted lists are
to be excluded. It then says that if the book specifies that an
argument must be a "list", it really means "true list"; that a
dotted list is an error.
A discussion of Destructuring macro arguments appears on P.146 . It
allows dotted lists as or within individual arguments in macro
calls -- e.g. (mac (foo . fum)), (mac (3 (foo . fum) 4)), and I read into
that an implication that I can expect &rest args (at least embedded ones)
to bind to dotted lists or non-NIL atoms. [I'd like to think that there
is nothing special about non-embedded &rest args -- that they, too, could
bind to dotted lists or non-NIL atoms. But I can't say that anything
on P.146 really implies that.]
P.146 also allows dotted lists in the lambda list of a macro definition, but
states that they are equivalent to something that could be written with
&rest.
----------------------------------------------------------------
So, just what is the intent of the use of "list" on pp. 54-59? Are dotted
lists portable as macro calls? If so, is &whole the only portable way
to accept them? What about as function calls? [there is no &whole
for function lambda lists.]
Incidentally, I believe I have a justifiable reason to want a dotted list
to be acceptable as a macro form. It would be slightly more convenient
if I could use a macro lambda list with an &REST in it, rather than
resorting to &WHOLE, but that's no big deal.
I would like to see the issue clarified so that
a) dotted lists are legal as macro calls (but not as function calls if
that forces added run-time costs in APPLY or ordinary function calling.)
b) &rest parameters in macro lambda lists may bind to dotted lists or
non-NIL atoms. This applies to top-level as well as embedded &rest
parameters.
Neil
∂15-Jun-88 0014 Common-Lisp-mailer smashed constants
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Jun 88 00:14:10 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac05994; 15 Jun 88 3:09 EDT
Received: from cs.umass.edu by RELAY.CS.NET id ak11087; 15 Jun 88 3:00 EDT
Date: Tue, 14 Jun 88 13:18 EDT
From: ELIOT@cs.umass.edu
Subject: smashed constants
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
>From: IN%"Moon@SCRC-STONY-BROOK.ARPA" "David A. Moon" 14-JUN-1988 03:46
>To: ELIOT@cs.umass.EDU
>Subj: constant folding/smashing
>
> Date: Fri, 10 Jun 88 11:32 EDT
> From: ELIOT@cs.umass.edu
>
> (I don't count #.(make-hash-table...) because it's so gross.)
>
>I object to the characterization of doing something through the normal
>syntax, instead of inventing a special weird syntax that people have
>to learn as a special case, as "gross."
Yes, that was a poor choice of words. But I don't think I am the only
one who considers "escape" constructs like #. to be a technique of last
resort.
Still, I think my abstract point holds. QUOTE is a very good way to
construct small and simple data structures, but there are many data
structures that cannot *reasonably* be constructed with it.
So QUOTE can't support a general mechanism for constructing read
only data. If Common Lisp is going to have a notion of read-only,
(for those implementations capable of it) then it would be best to
support a general mechanism for it.
Admittedly I don't know exactly how a general mechanism should be
defined. A straightforward recursive decent copy won't work
on circular data structures.
∂15-Jun-88 0014 Common-Lisp-mailer Constant Smashing
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Jun 88 00:14:22 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad05994; 15 Jun 88 3:09 EDT
Received: from cs.umass.edu by RELAY.CS.NET id al11087; 15 Jun 88 3:00 EDT
Date: Tue, 14 Jun 88 13:20 EDT
From: ELIOT@cs.umass.edu
Subject: Constant Smashing
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
>From: IN%"NGALL@G.BBN.COM" 14-JUN-1988 03:53
>Subj: Re: constant folding/smashing
>
> Date: Fri, 10 Jun 88 11:32 EDT
> From: ELIOT@cs.umass.edu
>
> What about constant hash-tables? No variety of QUOTE can build
> a constant hash table because there is no notation for them.
> (I don't count #.(make-hash-table...) because it's so gross.)
>
>Once again, I will state that the problem is not notation. QUOTE
>cannot cons its argument into RO-space because the argument has ALREADY
>BEEN CONSED. All QUOTE can do it to cons in RO-space an EQUAL COPY of
>its argument and return that copy. But there is NO SUCH THING as an
>EQUAL "COPY" of a hashtable. It doesn't matter that its gross, it
>just won't work.
Further supporting the idea that a general mechanism apart from QUOTE
is required to properly support read-only data structures, if read
only data becomes a Common Lisp concept.
> In general I like the idea of quoted constants being read-only,
> because it ensures that the semantics of a function at run-time
> are apparent from its textual representation as code. If constants
> are not read-only then:
>
> (defun foo ()
> '(a b c))
>
> Really means
>
> (defun foo ()
> G00047)
> (setq G00047 '(a b c))
>
>Funny, this is the semantics that most Lisper's have as their initial
>mental model (and I assume find the most intuitive).
I'm not sure the code expresses my point clearly. Functions that return
quoted constants are subject to *external* modification of their *internal*
behavior. Its likely that you can get accidentally self modifying code.
I've seen this cause obscure bugs. I don't think it is intuitive.
The source code for the first definition of FOO makes it notationally
"obvious" (incorrectly) that FOO always returns the list (A B C).
The source code for the second definition makes it notationally clear
that there is some global and mutable state involved.
>It is also the
>semantics of all (?) CL interpreters. QUOTE MUST have the same
>behavior in the compiler and the interpreter. To do otherwise is to
>introduce a compiler/interpreter incompatibility as confusing and
>error-prone as the SPECIAL variable incompatibility used to be. Agreed?
No. QUOTE must have the same *semantics* in the compiler and interpreter.
However, there may be aspects of the semantics that are not fully
defined and an implementation may have differences in those areas.
(The binding environment of a variable is deemed much too important
to leave unspecified.) It would be coherent to specify that it is
"an error" to modify a quoted constant without requiring an implementation
to ever detect it. A legitimate implementation might detect it some
of the time (on tuesdays and thursdays perhaps) but not at other times.
In the case of QUOTE some errors might go undetected. This is not good,
but it is not as dangerous a flaw as the SPECIAL variable problem,
which is characterized by different compiled/interpreted behavior
where neither behavior draws attention to the actual source of the
problem. It is relatively straightforward to debug a problem that
causes the debugger to freeze execution near the actual cause.
To support this argument I must make one more claim. I must claim that
compiling a function produces a *new* function definition that is
semantically equivalent to the old one, but it does not have to
be composed of the 'same' forms. This is because of the definition of
CONSTANTP on p.324 (CLtL) which (in my reading) implies (eq (foo) (foo))
when FOO is defined as above. [Because of (constantp (quote a b c))]
Therefore:
(eq (foo) (foo)) => T
(setq x (foo))
(compile 'foo)
(eq x (foo)) => Ambiguous
(eq (foo) (foo)) => T
And no identity holds accross the act of compilation.
>If you want to suggest that the interpreter should be changed to make
>QUOTE return a RO-EQUAL-copy of its arg when possible*** (as I think JonL
>may have been suggesting?), then consider what a pain it will cause at
>the top-level:
>
>> (setf foo '(1 2 3))
>(1 2 3)
>> (push 0 foo)
>>>>>> Error ...
Tsk, Tsk. THAT won't cause an error. You meant: (setf (car foo) 'one)?
An implementation can go either way on this. Experience with several
different implementations may show what the happy compromise is.
Actually I think that QUOTE should produce read only data structures
and BACKQUOTE should create newly CONSed mutable data structures.
>
>Instead, you'll have to do:
>
>> (setf foo (list 1 2 3))
Or use backquote.
>(1 2 3)
>> (push 0 foo)
>(0 1 2 3)
>
>A lot of Lisp textbooks will have to be rewritten!
>
>-- Nick
>
>*** Actually, the interpreter's handling of self-evaluating forms will
>have to be changed too.
If you agree with what I said about *external* modification of
*internal* behavior then it would have to apply to strings, characters
etc. also. But the added complexity is negligable, since "Foo"
or #\Foo could be treated as (quote "Foo") or (quote #\Foo).
∂15-Jun-88 0139 Common-Lisp-mailer smashed constants
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 15 Jun 88 01:39:53 PDT
Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Wed 15 Jun 88 03:38:14-CDT
Date: Wed, 15 Jun 88 03:37 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: smashed constants
To: ELIOT@cs.umass.edu
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: The message of 14 Jun 88 12:18 CDT from ELIOT@cs.umass.edu
Message-ID: <880615033739.2.GUMBY@BRAHMA.ACA.MCC.COM>
Date: Tue, 14 Jun 88 13:18 EDT
From: ELIOT@cs.umass.edu
Still, I think my abstract point holds. QUOTE is a very good way to
construct small and simple data structures, but there are many data
structures that cannot *reasonably* be constructed with it.
So QUOTE can't support a general mechanism for constructing read
only data. If Common Lisp is going to have a notion of read-only,
(for those implementations capable of it) then it would be best to
support a general mechanism for it.
I think this is also KMP's point, but I can't dig up that message, so:
It should never be the Lisp's responsibility. If an implementation
wants to support read-only-ness then it should be explicit.
Perhaps one may say (copy-list-into-read-only-space <list>) or
(copy-tree... ). That removes from the implementation the
responsibility of deciding the level provided (i.e. you can move
whatever you want into read-only space, as you wish. You could have a
read-only array containing lists which existed in read/write space, for
instance.)
Note that you can then get the quote behavior you want by doing
(defvar +some-internal-list+ (copy-list-into-read-only-space *another-list*))
(defun foo (x) (cons x (quote #,+some-internal-list+)))
I think you are confusing the meaning of QUOTE, which is merely a kind
of SUPPRESS-EVAL.
∂15-Jun-88 0817 Common-Lisp-mailer Re: Constant Smashing
Received: from G.BBN.COM ([8.2.0.18]) by SAIL.Stanford.EDU with TCP; 15 Jun 88 08:17:47 PDT
Date: 15 Jun 1988 11:15-EDT
Sender: NGALL@G.BBN.COM
Subject: Re: Constant Smashing
From: NGALL@G.BBN.COM
To: common-lisp@SAIL.STANFORD.EDU
Message-ID: <[G.BBN.COM]15-Jun-88 11:15:54.NGALL>
In-Reply-To: The message of Tue, 14 Jun 88 13:20 EDT from ELIOT@cs.umass.edu
Date: Tue, 14 Jun 88 13:20 EDT
From: ELIOT@cs.umass.edu
...
Further supporting the idea that a general mechanism apart from QUOTE
is required to properly support read-only data structures, if read
only data becomes a Common Lisp concept.
Agreed.
> (defun foo ()
> '(a b c))
>
> Really means
>
> (defun foo ()
> G00047)
> (setq G00047 '(a b c))
>
I'm not sure the code expresses my point clearly. Functions that return
quoted constants are subject to *external* modification of their *internal*
behavior. Its likely that you can get accidentally self modifying code.
I've seen this cause obscure bugs. I don't think it is intuitive.
The source code for the first definition of FOO makes it notationally
"obvious" (incorrectly) that FOO always returns the list (A B C).
The source code for the second definition makes it notationally clear
that there is some global and mutable state involved.
I think the 2nd definition is MORE misleading. Yes it does suggest
"that there is some global and mutable state involved", but it
suggests that the wrong thing is modifiable. By using a special var,
it suggests that the reference is mutable. But that is exactly what
is CONSTANT (and I claim the ONLY thing that is constant) in the 1st
def. What IS mutable (which neither def. suggests strongly enough) is
the list itself. Again this suggests a different notation for RO is
needed.
>It is also the
>semantics of all (?) CL interpreters. QUOTE MUST have the same
>behavior in the compiler and the interpreter. To do otherwise is to
>introduce a compiler/interpreter incompatibility as confusing and
>error-prone as the SPECIAL variable incompatibility used to be. Agreed?
No. QUOTE must have the same *semantics* in the compiler and
interpreter. I was unclear. I meant that the compiler and
interpreter must BEHAVE identically. My point is a pedagogical one:
people learn lisp in the interpreter. Textbooks use (and motivate)
QUOTE as if ALL that it does it to prevent evaluation and interpreters
support this model. I feel would not be sufficient for CLtL to merely
state that "it is an error" to modify the arg of QUOTE and enforce in
in the compiler but not the interpreter. This is what leads to the
continual confusion of neophytes.
In the case of QUOTE some errors might go undetected. This is not good,
but it is not as dangerous a flaw as the SPECIAL variable problem,
which is characterized by different compiled/interpreted behavior
where neither behavior draws attention to the actual source of the
problem. It is relatively straightforward to debug a problem that
causes the debugger to freeze execution near the actual cause.
Three: 1) What if the the RO-ness of the object was the bug.
Finding the source of the object could be very difficult. 2) I have
heard from at least 2 lisp implementors (on stock harware) that they
will not enforce the RO-ness of a QUOTEd object until system build
time, not compile time! It takes us over an hour to build our system.
What a debug cycle! :-) [Actually this brings up the general issue of
a third kind of "code": interpreted, compiled, and "built".] 3) Its
not the debugging difficulty alone that bothers me, it is mere
difference in behavior between the compiler and interpreter in a very
common case.
To support this argument I must make one more claim. I must claim that
compiling a function produces a *new* function definition that is
semantically equivalent to the old one, but it does not have to
be composed of the 'same' forms.
Agreed.
This is because of the definition of
CONSTANTP on p.324 (CLtL) which (in my reading) implies (eq (foo) (foo))
when FOO is defined as above. [Because of (constantp (quote a b c))]
Disagree. CONSTANTP uses the vague expression "evaluate to the same
thing". Which version of SAME is it talking about? EQ EQL or EQUAL
Can't be EQ since CONSTANTP is true of numbers. I claim SAME means
EQUAL, because of CLtLs EQUAL constant collapsing which IN THEORY
allows QUOTE to cons an EQUAL copy of its argument each time the QUOTE
form is evaluated. (As my pseudo-definition of QUOTE stated in a
previous message.)
Therefore:
(eq (foo) (foo)) => T
(setq x (foo))
(compile 'foo)
(eq x (foo)) => Ambiguous
(eq (foo) (foo)) => T
No. (eq (foo) (foo)) => Ambiguous. This is why I want to flush EQUAL
constant collapse from CLtL. I want it to be T.
And no identity holds accross the act of compilation.
>If you want to suggest that the interpreter should be changed to make
>QUOTE return a RO-EQUAL-copy of its arg when possible*** (as I think JonL
>may have been suggesting?), then consider what a pain it will cause at
>the top-level:
>
>> (setf foo '(1 2 3))
>(1 2 3)
>> (push 0 foo)
>>>>>> Error ...
Tsk, Tsk. THAT won't cause an error. You meant: (setf (car foo) 'one)?
Yes. Sorry about that. I really meant (push 0 (rest foo)).
-- Nick
∂15-Jun-88 1624 Common-Lisp-mailer Constant Smashing
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 15 Jun 88 16:24:19 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 15 Jun 88 19:29:37 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 15 Jun 88 19:29:31 EDT
Date: Wed, 15 Jun 88 19:21 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Constant Smashing
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8806150722.AB20102@Think.COM>
Message-Id: <19880615232125.4.BARMAR@OCCAM.THINK.COM>
Date: Tue, 14 Jun 88 13:20 EDT
From: ELIOT@cs.umass.edu
If you agree with what I said about *external* modification of
*internal* behavior then it would have to apply to strings, characters
etc. also. But the added complexity is negligable, since "Foo"
or #\Foo could be treated as (quote "Foo") or (quote #\Foo).
Minor nit: Characters do not have mutable components.
(let* ((char #\Foo)
(char2 char))
(setf (char-code char) (char-code #\Bar))
char2)
will return #\Foo, not #\Bar.
barmar
∂15-Jun-88 2004 Common-Lisp-mailer copy
Received: from IBM.COM by SAIL.Stanford.EDU with TCP; 15 Jun 88 20:03:54 PDT
Date: 15 Jun 88 22:52:41 EDT
From: Timothy Daly <DALY@ibm.com>
To: common-lisp@sail.stanford.edu
Message-Id: <061588.225242.daly@ibm.com>
Subject: copy
Is there some reason why there isn't a general purpose COPY function
in common lisp?
Tim
DALY@IBM.COM
∂15-Jun-88 2056 Common-Lisp-mailer copy
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Jun 88 20:56:33 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 420390; Wed 15-Jun-88 23:55:17 EDT
Date: Wed, 15 Jun 88 23:55 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: copy
To: DALY@ibm.com
cc: common-lisp@sail.stanford.edu
In-Reply-To: <061588.225242.daly@ibm.com>
Message-ID: <880615235500.0.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: 15 Jun 88 22:52:41 EDT
From: Timothy Daly <DALY@ibm.com>
Is there some reason why there isn't a general purpose COPY function
in common lisp?
Tim
DALY@IBM.COM
This question gets asked a lot. Here's my personal assessment. I suspect
the answers will vary widely, though:
You don't know how much to copy without understanding the intent of an
object. If there were just 1 copy function and you wrote:
(COPY '((A . B) . ((C . D) . NIL)))
how would you know whether to use COPY-CONS (if there were such a thing),
COPY-LIST, or COPY-ALIST?
In my opinion, the issues are the same for COPY as they are for EQUAL.
We did provide EQUAL but people complain all the time that it doesn't
"do the right thing".
The truth is that there is no unique right thing in either case.
In the case of COPY, whether you've copied enough depends on what parts
you consider "the container" and what parts you consider the "contents".
Since there can be different views on the same object, no unique function
can do the whole job.
In the case of EQUAL, the issue is similar. The function you should be
calling to determine if two things are "enough alike" (which is pretty
much what equal seems to mean to people) really depends on your intended
use. I claim that read about EQUAL and then try to invent uses and that's
why it always seems to be broken -- because they want minor perturbations
around this thing they started from. If we'd not given them something to
center their misconceptions around, they would be more likely to just
think of equality as an ill-defined (read: application-specific) problem
rather than to think that it must be uniquely determined in the absence
of an application. Consider having your boss say "Go get me someone who's
Sally's equal." It might help to know if he was looking for someone to
use on the next important work-related project or someone to substitute
on the bowling team tonight. It is not a property of Sue, Bill, or George
what EQUAL means; it is a property of the thing you intend to do with
them afterward, so (EQUAL SUE SALLY) is not the right thing. Instead, you
want (WORK-EQUAL SUE SALLY) and (BOWLING-EQUAL SUE SALLY) and so on.
Similarly, if someone was writing something down on a piece of paper
and someone asked you to "copy what they were writing", it would help for
you to know if they were planning to film your actions, take the copy
of what they'd written home to read later, or use your copy as a forgery.
Depending on the application, your actions might be very different.
The issue of what to do to fix EQUAL is before the cleanup committee
and a zillion solutions have been raised. I've suggested that the most
reasonable thing is to flush EQUAL but for pragmatic reasons we probably
will not. Still, by retaining it, people are left with the sense that
EQUAL computes "uniquely determined generic equality" when in fact it
computes "often useful but quite arbitrary equality". Perhaps someday
someone will add COPY (though I will steadfastly oppose it) but at the
very least I hope the documentation will make clear how arbitrary the
choice of its action is.
Note: It recently occurred to me that saying
(EQUAL X Y 'CONS), (EQUAL X Y 'TREE), (EQUAL X Y 'BOWLER), etc.
-- that is, adding an "abstract view" argument -- might give us a
handle on things. I think people would tend to see this as redundant,
and maybe it could even default to (TYPE-OF object). Similarly,
(COPY X Y 'CONS), (COPY X Y 'BOWLER), etc. might give you enough
information to know what the salient aspects were... Naturally, to
be really useful, you'd need to be able to customize the way in
which any user-defined type was copied,etc. Anyway, I'm not
endorsing this idea, just mentioning it as a thing to be looked at.
∂16-Jun-88 1009 Common-Lisp-mailer L&FP Registration Forms
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Jun 88 10:04:33 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA09090; Thu, 16 Jun 88 11:03:06 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA10764; Thu, 16 Jun 88 11:02:58 MDT
Date: Thu, 16 Jun 88 11:02:58 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8806161702.AA10764@cons.utah.edu>
To: common-lisp@sail.stanford.edu, scheme@sail.stanford.edu
Subject: L&FP Registration Forms
Apparently many people have not yet received the advance registration
forms from ACM. Supposedly, it was sent to all members of SIGPLAN,
SIGART, and SIGACT, along with about 250 of the people who attended
the 1986 conference (this was supposed to go to over 20,000 people).
Anyway, here is a pseudo electronic version of registration form.
Please provide ACM with all of this information detailed here.
Thanks.
Bob.
====================== L&FP 88 Registration Form ====================
The registration fees for applications prior to June 24 are:
Student $75
ACM or SIG (PLAN, ART, or ACT) Member Only $250
ACM and SIG Member $225
Non-Member $290
The registration fees for applications after that date are:
Student $100
ACM or SIG (PLAN, ART, or ACT) Member Only $300
ACM and SIG Member $275
Non-Member $350
Additional banquet tickets (for students or guests) are $40
Additional luncheon tickets are $12.50
Make your own application form including
Your Name
Company/Institution
Address
Telephone
E-mail Address
Membership status in ACM and SIGPLAN/SIGART/SIGACT including
membership number
Your fee category (as described above)
Your order for any extra banquet or luncheon tickets
Total fees enclosed
Form of payment (check/credit card)
Credit card type (Mastercard, Visa, or Amer Express), number,
and signature if paying by credit card
Mailing List Restriction: (one of No Restictions, ACM and Other
Society Announcements, ACM Announcements)
If paying by check, make check payable (in US funds only!) to:
ACM LFP '88
Mail your form and payment to:
ACM LFP '88
P.O. Box 12105
Church Street Station
New York, NY 10249
∂16-Jun-88 1016 Common-Lisp-mailer More on L&FP Registration Forms
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Jun 88 10:16:37 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA09783; Thu, 16 Jun 88 11:15:22 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA10799; Thu, 16 Jun 88 11:15:20 MDT
Date: Thu, 16 Jun 88 11:15:20 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8806161715.AA10799@cons.utah.edu>
To: common-lisp@sail.stanford.edu
Subject: More on L&FP Registration Forms
According to the US Post Office, 16,000 pieces were mailed on May
10... (the rest that had to go overseas and first class were mailed
before that).
Sigh....
Bob.
∂17-Jun-88 1017 Common-Lisp-mailer Re: constant folding/smashing
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 17 Jun 88 10:17:17 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA17871; Fri, 17 Jun 88 10:13:58 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA03167; Fri, 17 Jun 88 10:10:15 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA01554; Fri, 17 Jun 88 10:16:38 PDT
Date: Fri, 17 Jun 88 10:16:38 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8806171716.AA01554@clam.sun.com>
To: ELIOT@cs.umass.edu, Moon@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: constant folding/smashing
Cc: common-lisp@SAIL.STANFORD.EDU
> (I don't count #.(make-hash-table...) because it's so gross.)
>
> I object to the characterization of doing something through the normal
> syntax, instead of inventing a special weird syntax that people have
> to learn as a special case, as "gross."
>
I would like to add my agreement to David Moon's statement. With the
#. readmacro you don't have to learn extra syntax to understand the
printed representation, and it is nothing if not adequately general.
∂19-Jun-88 1717 Common-Lisp-mailer #, read macro
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 19 Jun 88 17:17:02 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA01138; Sun, 19 Jun 88 18:15:26 MDT
From: sandra@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8806200015.AA01138@cs.utah.edu>
Date: Sun, 19 Jun 88 18:15:25 MDT
Subject: #, read macro
To: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu
One of the items currently before the X3J13 compiler cleanup
subcommittee is tightening up the definition of how the #, (sharp-sign
comma) read macro should work, and where it may legitimately appear in
code to be compiled. We are considering (among other options) removing
it from Common Lisp entirely. Since this would clearly be an
incompatible change to the language, we would like to hear from people
who actually use #, to find out how it is being used and whether some
other technique(s) couldn't be used to solve the same problems.
Please send replies on this subject to cl-compiler@sail.stanford.edu.
-Sandra
-------
∂19-Jun-88 2355 Common-Lisp-mailer #, read macro
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 19 Jun 88 23:55:38 PDT
Received: from PELE.ACA.MCC.COM by MCC.COM with TCP/SMTP; Mon 20 Jun 88 01:53:45-CDT
Date: Mon, 20 Jun 88 01:52 CDT
From: Christopher Maeda <maeda@MCC.COM>
Subject: #, read macro
To: sandra@cs.utah.edu, common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu
cc: bug-cyc@MCC.COM
In-Reply-To: <8806200015.AA01138@cs.utah.edu>
Message-ID: <19880620065222.1.MAEDA@PELE.ACA.MCC.COM>
We are implementing a frame system where each frame is a defstruct. We
use a reader macro to reference case sensitive frame names, permitting
the frame namespace to be disjoint from the symbol namespace. The
reader macro also lets us hook into a completion package that is very
handy for longer names.
I would be interested in hearing what alternatives the cleanup committee
is considering. Being able to dispatch to an arbitrary read function is
hard to beat.
--Chris
∂20-Jun-88 1006 Common-Lisp-mailer #, read macro
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 20 Jun 88 10:06:29 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 20 Jun 88 13:11:08 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 20 Jun 88 13:11:05 EDT
Date: Mon, 20 Jun 88 13:03 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: #, read macro
To: Christopher Maeda <maeda@mcc.com>
Cc: sandra@cs.utah.edu, common-lisp@sail.stanford.edu,
cl-compiler@sail.stanford.edu, bug-cyc@mcc.com
In-Reply-To: <19880620065222.1.MAEDA@PELE.ACA.MCC.COM>
Supersedes: <19880620170243.2.BARMAR@OCCAM.THINK.COM>
Message-Id: <19880620170302.3.BARMAR@OCCAM.THINK.COM>
Date: Mon, 20 Jun 88 01:52 CDT
From: Christopher Maeda <maeda@mcc.com>
We are implementing a frame system where each frame is a defstruct. We
use a reader macro to reference case sensitive frame names, permitting
the frame namespace to be disjoint from the symbol namespace. The
reader macro also lets us hook into a completion package that is very
handy for longer names.
I would be interested in hearing what alternatives the cleanup committee
is considering. Being able to dispatch to an arbitrary read function is
hard to beat.
--Chris
No one is talking about removing reader macros in general. We are
considering removing the "#," reader macro. "#," is a relatively
obscure cousin of "#."; it causes the form following it to be
evaluated at load time rather than at read time as "#." does.
To see how it currently works, put the following definition in a file:
(defun sharp-comma-example ()
(quote #,*sharp-comma-var*))
Compile the file, type (setq *sharp-comma-var* 'a), then load the binary
file. Then type (setq *sharp-comma-var* 'b) and (sharp-comma-example).
It should return A.
barmar
∂20-Jun-88 1237 CL-Compiler-mailer Re: #, read macro
Received: from gremlin.nrtc.northrop.com by SAIL.Stanford.EDU with TCP; 20 Jun 88 12:37:05 PDT
Received: from tribble by gremlin.nrtc.northrop.com id a018817;
20 Jun 88 12:22 PDT
To: Sandra J Loosemore <sandra@cs.utah.EDU>
cc: common-lisp@sail.stanford.EDU, cl-compiler@sail.stanford.EDU,
jbarnett@gremlin.nrtc.northrop.COM
Subject: Re: #, read macro
In-reply-to: Your message of Sun, 19 Jun 88 18:15:25 -0600.
<8806200015.AA01138@cs.utah.edu>
Date: Mon, 20 Jun 88 12:22:53 -0700
From: jbarnett@gremlin.nrtc.northrop.COM
One use of this construct is to simulate ALGOL-like OWN variables; to wit:
(defun foo (arg ... &aux (var '#,<complex expression>))
body that references var...)
where the <complex expression> is computed in terms of previously defined
defvars, defuns, etc., and you don't want to create yet another only-used-in
one-place special variable, e.g.,
(defvar *foos-own* <complex expression>)
(defun foo (args ...)
body that reference *foos-own* insteadof var...)
By the way, there's not much use to trying to clean up the use of #, until
you do a better job of defining EVAL-WHEN (or whatever you call it now).
If you do that properly, not only will #, be easy to understand, implement, and
use, but I'd guess that several natural and useful extentions will occur.
Jeff
∂23-Jun-88 1144 Common-Lisp-mailer constant smashing
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 23 Jun 88 11:44:24 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ad08061; 23 Jun 88 12:54 EDT
Received: from cs.umass.edu by RELAY.CS.NET id dl18009; 23 Jun 88 12:41 EDT
Date: Thu, 23 Jun 88 11:21 EDT
From: ELIOT@cs.umass.edu
Subject: constant smashing
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
>From: IN%"NGALL@G.BBN.COM" 17-JUN-1988 07:02
>Subj: Re: Constant Smashing
>
> From: ELIOT@cs.umass.edu
>
> ...
> Further supporting the idea that a general mechanism apart from QUOTE
> is required to properly support read-only data structures, if read
> only data becomes a Common Lisp concept.
>
>Agreed.
>
...
> > (defun foo ()
> > '(a b c))
> >
> > Really means
> >
> > (defun foo ()
> > G00047)
> > (setq G00047 '(a b c))
> >
>What IS mutable (which neither def. suggests strongly enough) is
>the list itself. Again this suggests a different notation for RO is
>needed.
THAT is my point. In particular def. 1 does not suggest it strongly
enough for it to be a reasonable interpretation. In fact, def. 1
strongly suggests that it will always return (A B C). The source
code makes this reading so natural that I think it must be chosen
as the defined semantics, regardless of the context that FOO
is executed in. It is completely unnatural to allow some other
function to reach out of nowhere and dig around in the guts of
FOO resulting in changes to its behavior.
Intentionally modifying a quoted constant does not provide any
functionality that cannot be achieved using a global variable.
The global variable can be encapsulated in a lexical closure
to make its use even clearer. This easilly produces the same
effects and the code will more closely approximate its true
intention.
>>
>> >It is also the
>> >semantics of all (?) CL interpreters. QUOTE MUST have the same
>> >behavior in the compiler and the interpreter. To do otherwise is to
>> >introduce a compiler/interpreter incompatibility as confusing and
>> >error-prone as the SPECIAL variable incompatibility used to be. Agreed?
>>
>>No. QUOTE must have the same *semantics* in the compiler and
>>interpreter.
>I was unclear. I meant that the compiler and
>interpreter must BEHAVE identically. My point is a pedagogical one:
>people learn lisp in the interpreter. Textbooks use (and motivate)
>QUOTE as if ALL that it does it to prevent evaluation and interpreters
>support this model. I feel would not be sufficient for CLtL to merely
>state that "it is an error" to modify the arg of QUOTE and enforce in
>in the compiler but not the interpreter. This is what leads to the
>continual confusion of neophytes.
(1) If Common Lisp does not specify the behavior in some case an
implementation is free to do anything at all. It could be said that
Common Lisp will "Signal an error if any attempt is made to modify
a quoted constant" and then the compiler/interpreter would have
to behave identically. Since this is not practical for all implementations
the phase "It is an error" must be used instead.
(2) Textbooks can only be granted limited authority over *proposed*
changes. If Common Lisp changes or gets clarified then the textbooks
will have to be updated. Otherwise the situation is a little like
having the tail wag the dog.
(3) You can't learn *any* portable language by experimenting with it
if any part of the specification is incomplete. Experimentation
shows the behavior of the *implementation* but cannot distinguish
between the core language and its extensions. Before Common Lisp
the implementation was the specification, so this was not a problem.
In the future textbooks and teaching material must emphasize the
difference, and provide cautions about assuming trusting experimentally
revealed behavior. If it is not DOCUMENTED then you can't trust it.
>
> In the case of QUOTE some errors might go undetected. This is not good,
> but it is not as dangerous a flaw as the SPECIAL variable problem,
> which is characterized by different compiled/interpreted behavior
> where neither behavior draws attention to the actual source of the
> problem. It is relatively straightforward to debug a problem that
> causes the debugger to freeze execution near the actual cause.
>
>Three: 1) What if the the RO-ness of the object was the bug.
>Finding the source of the object could be very difficult.
One measure of bug "complexity" is how much of the actual
cause of the bug (code or data) will be "obvious" when the
bug occurs. Wrong numbers might have come from anywhere,
so they can be very hard to debug. RO-ness will at least
cause the debugger to point at the data structure that
is involved, but probably not the code. Thus, at worst,
it would be classified as a medium difficult bug.
>2) I have
>heard from at least 2 lisp implementors (on stock harware) that they
>will not enforce the RO-ness of a QUOTEd object until system build
>time, not compile time! It takes us over an hour to build our system.
>What a debug cycle! :-)
Patching avoids the need to go all the way around the debug
cycle.
>[Actually this brings up the general issue of
>a third kind of "code": interpreted, compiled, and "built".] 3) Its
>not the debugging difficulty alone that bothers me, it is mere
>difference in behavior between the compiler and interpreter in a very
>common case.
To rationally decide if a difference is "reasonable" requires something
like a cost/benefit analysis. The benefit is measured in terms of
efficieciency and simplicify of the implementation. What measures
the cost? It must be a combination of the likelihood that a bug
will come of it, and the difficulty of finding the bug. So I claim
that you *should* be primarilly concerned with the difficulty
of finding the bug that *should* determine if the mere difference
alone is bothersome.
>
> To support this argument I must make one more claim. I must claim that
> compiling a function produces a *new* function definition that is
> semantically equivalent to the old one, but it does not have to
> be composed of the 'same' forms.
>Agreed.
> This is because of the definition of
> CONSTANTP on p.324 (CLtL) which (in my reading) implies (eq (foo) (foo))
> when FOO is defined as above. [Because of (constantp (quote a b c))]
>
>Disagree. CONSTANTP uses the vague expression "evaluate to the same
>thing". Which version of SAME is it talking about? EQ EQL or EQUAL
>Can't be EQ since CONSTANTP is true of numbers. I claim SAME means
>EQUAL, because of CLtLs EQUAL constant collapsing which IN THEORY
>allows QUOTE to cons an EQUAL copy of its argument each time the QUOTE
>form is evaluated. (As my pseudo-definition of QUOTE stated in a
>previous message.)
I assumed that SAME meant EQL. Obviously that should be clarified.
I never heard of CONSTANTP before, so I speak from experience: none of it.
> Therefore:
[1] > (eq (foo) (foo)) => T
> (setq x (foo))
> (compile 'foo)
[2] > (eq x (foo)) => Ambiguous
[3] > (eq (foo) (foo)) => T
>
>No. (eq (foo) (foo)) => Ambiguous. This is why I want to flush EQUAL
>constant collapse from CLtL. I want it to be T.
I agree that [1] & [3] *should* be T, especially if EQL is substituted for EQ.
I don't care about EQUAL constant collapse, but it seems harmless
if you accept RO.
>
> And no identity holds accross the act of compilation.
Chris Eliot
∂24-Jun-88 1552 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 Jun 88 15:52:08 PDT
Received: by labrea.stanford.edu; Fri, 24 Jun 88 15:52:02 PDT
Received: from bhopal.lucid.com by edsel id AA07541g; Fri, 24 Jun 88 14:38:25 PDT
Received: by bhopal id AA16670g; Fri, 24 Jun 88 14:38:05 PDT
Date: Fri, 24 Jun 88 14:38:05 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806242138.AA16670@bhopal.lucid.com>
To: RWK@ai.ai.mit.edu
Cc: edsel!jlm@labrea.stanford.edu, common-lisp@sail.stanford.edu,
cl-cleanup@sail.stanford.edu
In-Reply-To: "Robert W. Kerns"'s message of Mon, 13 Jun 88 02:05:15 EDT <396357.880613.RWK@AI.AI.MIT.EDU>
Subject: EQUAL
[apologies for so late a reply -- have been out of town for over a week]
Jim's point about the historical reference of EQUAL seemed to me to be that
it was made to work for the datatypes that were "in common use" in the Lisps
of that day, namely the datatypes necessary for writing programs in the
Lisp language. Hence, conses, symbols, numbers, maybe strings, and not
much else.
However, I certainly wouldn't expect anything productive to come from a
discussion on how to determine whether two programs/functions *really*
are "equal"! Possibly you took MacDonald's argument to an extreme that
he didn't originally intend?
What would be the objections to extending EQUAL to accommodate the serious
modern datatypes of Common Lisp? in particular:
(1) Do component-wise EQUAL comparisons on arrays [this implies "descent"
for pointer arrays]. Unlike with EQUALP, the arrays must be of the
same type, but the presence of fill-pointers, array-element-type
"upgrading", adjustability, and displacement may require some
refinements of this clause.
(2) Descend defstructs, except possibly for "system" defstructs that
are built-in by the implementation [i.e., an implementation can
use defstruct to implement a STREAM, but impose a "private"
definition of EQUAL for streams; probably same for all types
discussed in the cleanup issue TYPE-HIERARCHY-UNDERSPECIFIED].
Possibly extend defstruct to admit an option :equal, similar to
the :copier option, but this isn't a critical requirement now.
(3) Require that EQUAL be a "generic" function, so that CLOS methods
can be written for it; likely, the "default" method for non-built-in
classes would be some sort of error, meaning that mindless descent
isn't a good default. By analogy with defstructs, you can compare
two defstuct-instances of the same type with the :equal functions,
and you could only compare two clos instances for which there is an
appropriate EQUAL method supplied.
This definition would imply that hashtables of :type EQUAL will operate in
the manner expected by so many users of Common Lisp. Somehow, people have
been lured into thinking that this is already the current practice; but of
course something much more limiting is the current state.
Finally, I might point out that recent discussions about EQUALP seem to
have overlooked it's variations on numerical equality and array-type
indifference. Extending EQUAL to descend structures is *not* the same
as retracting EQUALP to be case-sensitive.
-- JonL --
∂24-Jun-88 1614 Common-Lisp-mailer constant folding/smashing
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 Jun 88 16:14:24 PDT
Received: by labrea.stanford.edu; Fri, 24 Jun 88 16:14:19 PDT
Received: from bhopal.lucid.com by edsel id AA07969g; Fri, 24 Jun 88 16:02:57 PDT
Received: by bhopal id AA17926g; Fri, 24 Jun 88 16:02:36 PDT
Date: Fri, 24 Jun 88 16:02:36 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806242302.AA17926@bhopal.lucid.com>
To: RWK@ai.ai.mit.edu, NGALL@g.bbn.com
Cc: common-lisp@sail.stanford.edu, goldman@vaxa.isi.edu
In-Reply-To: "Robert W. Kerns"'s message of Mon, 13 Jun 88 02:31:18 EDT <396377.880613.RWK@AI.AI.MIT.EDU>
Subject: constant folding/smashing
re: Date: Mon, 13 Jun 88 02:31:18 EDT
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
. . .
[jonl: Symbols are atomic, and don't have 'components']
. . .
[rwk:]
(SETF (SYMBOL-VALUE 'X) 1)
is the same as
(SETQ X 1), for X being special.
The X in either piece of code is a REFERENCE to a non-constant
object, shared between occurrances of read. It is a PUBLIC structure
published by INTERN. Modifications to its value cell are modifications
to the global variable environment. They're already EQified as much as
makes sense.
If you had quoted my full message to which you are replying, there would
have been a reference to the several implemtations of Common Lisp that
do not implement special variables via a "component, value-cell". It was
the explicit intent of the authors of CLtL that "deep binding" schemes not
be proscribed; your description quoted just above is a model for a shallow-
binding implementation. As moon has also pointed out, one should not mistake
the accidents of a paritcular implementation for the underlying semantics of
a construct.
Now, I will admit that Lisp'ers frequently speak of a symbol's value-cell,
or it's function cell; but this is language rooted in a now outdated past.
It's ok to use that language, so long as everyone understands that there
need not be an actual record structure with such components in it. Remember
in VAX/NIL how the only implementation component was a "multiplex" cell,
which would lazily create an auxiliary four-component data structure when
necessary? The term "value-cell" in that implementation was merely a
shorthand for a much more complex implementational scheme.
re: Date: 13 Jun 1988 18:50-EDT
Sender: NGALL@G.BBN.COM
. . .
If you want to suggest that the interpreter should be changed to make
QUOTE return a RO-EQUAL-copy of its arg when possible*** (as I think JonL
may have been suggesting?), then consider what a pain it will cause at
the top-level:
> (setf foo '(1 2 3))
(1 2 3)
> (push 0 foo)
>>>>> Error ...
First off, you should re-examine the semantics of PUSH -- I think you will
find that it modifies the value of the variable FOO rather than the quoted
data structure of your example. In virtually every implementation of CL,
(macroexpand-1 '(push 0 foo)) ==> (setq foo (cons 0 foo))
You may also want to remember the potential for read-only objects [which I
think I discussed in a previous note -- Interlisp-D had read-only strings?].
I suppose it would almost be an acceptable implementation of QUOTE to make
it's "argument" be a read-only object (when possible), rather than returning
a non-EQ-but-EQUAL read-only copy; but I dislike this approach since it
requires modifying the data-structure representing the program during the
running of the program itself.
re: All QUOTE can do [is] to cons in RO-space an EQUAL COPY of
its argument and return that copy. But there is NO SUCH THING as an
EQUAL "COPY" of a hashtable. It doesn't matter that its gross, it
just won't work.
If you are referring to my "canonicalization" version of QUOTE, you should
recall that two "quoted" constants were coalesced *not* when they were
EQUAL, but under a more permissive predicate. It is not an EQUAL copy
that one wants, but an "equivalent" one. There are such things as
"coalescable" hash-tables, and they work quite well in Lucid Common Lisp;
I described their use in my note to Eliot dated Sat, 11 Jun 88 17:46:49 PDT.
-- JonL --
P.S.: That the "push" typo/braino should go unnoticed so long suggests that
no one else is really reading these interchanges. If anyone on the
mailing list feels they are not useful interchanges (and is actually
reading this post-script!), he should speak up now!
∂24-Jun-88 1647 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 Jun 88 16:47:22 PDT
Received: by labrea.stanford.edu; Fri, 24 Jun 88 16:46:48 PDT
Received: from bhopal.lucid.com by edsel id AA08086g; Fri, 24 Jun 88 16:40:19 PDT
Received: by bhopal id AA18154g; Fri, 24 Jun 88 16:39:58 PDT
Date: Fri, 24 Jun 88 16:39:58 PDT
From: Jim McDonald <edsel!jlm@labrea.stanford.edu>
Message-Id: <8806242339.AA18154@bhopal.lucid.com>
To: edsel!jonl@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: Jon L White's message of Fri, 24 Jun 88 14:38:13 EST <8806242138.AA16670@bhopal.lucid.com>
Subject: EQUAL
My concern about having EQUAL descend structures and arrays is that
they are much more likely than lists to be circular.
Typically, a list is created after its elements, whereas a structure
or array is created before its elements. (*Typically*, not always!)
As a rule of thumb, I'd bet that less than .0001% of all lists are
circular, and that less than 1% of all arrays are circular, but only
that less than 30% of all structures are circular.
I think there is a tendancy to include fields like CHILDREN and
PARENTS, or PREVIOUS and NEXT, etc. in structures, which are thus
almost guaranteed to be circular. In fact, when I'm creating circular
data I tend to think first of using structures, because I am then less
likely to get screwed by EQUAL, etc.
I don't have time now to think through the algorithmic details, but
maybe DEFSTRUCT could let you specify that specific slots are
"back-pointers". Then EQUAL could record them when descending and
perform a more sophisticated comparison than it would for all other
pointers. Thus you would only pay at runtime for the specific
complications you did introduce, not those you might have. Making
backpointers explicit might help human readability as well.
[As something of an aside, I think you should also be able to specify
*print-level* and *print-length* for specific structure fields, to
avoid losing on some fields when trying to see others.]
jlm
∂24-Jun-88 1709 Common-Lisp-mailer #.
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 24 Jun 88 17:08:57 PDT
Received: by labrea.stanford.edu; Fri, 24 Jun 88 17:08:56 PDT
Received: from bhopal.lucid.com by edsel id AA08136g; Fri, 24 Jun 88 16:56:18 PDT
Received: by bhopal id AA19214g; Fri, 24 Jun 88 16:56:00 PDT
Date: Fri, 24 Jun 88 16:56:00 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806242356.AA19214@bhopal.lucid.com>
To: cperdue@sun.com
Cc: ELIOT@cs.umass.edu, Moon@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
In-Reply-To: Cris Perdue's message of Fri, 17 Jun 88 10:16:38 PDT <8806171716.AA01554@clam.sun.com>
Subject: #.
re: > (I don't count #.(make-hash-table...) because it's so gross.)
. . .
I would like to add my agreement to David Moon's statement. With the
#. readmacro you don't have to learn extra syntax to understand the
printed representation, and it is nothing if not adequately general.
Let's just say that it is "nothing". The problem with #. is precisely that
it is not syntax; rather, it is an "out" where the designers of the language
failed to come up with a syntax. To see this more clearly, consider writing
a trivial C program to read in "simple" Lisp expressions into equivalent data
structures of the C world. Parsing is no real problem [maybe could even
be yacc'd away], INTERNing of symbols is just a table lookup, numbers is
numbers [hey, even C can do fixnums and floats!], defstructs can be structs,
strings are strings, and so on; cons cells etc. can be cut out of mallocated
space, and pointer-type variables make it easly to link things together.
But there is no reasonable equivalent for the #. requirements -- no matter
how trivial the data-type returned, it implies the existence of a Lisp
EVALuator just to parse-&-build the representation. That's a LOT to require
for merely constructing up some simple data structures.
Thus while #. could be viewed as an adequate escape mechanism, it certainly
couldn't be part of a general interchange language.
And yet the hard problems are not limited to the "interchange" cases.
Consider file-processors other than LOAD or COMPILE-FILE (such as the
cross-reference program described by Tom Gruber in the first issue of
Lisp Pointers). Such a processor will want to READ a file of Lisp code,
but not necessarily evaluate anything in it. How will it react to the
file [named, say "/u/loser/trojan-horse.lisp"]:
(defun gift-horse (x)
#.(progn (punch-paper-tape)
(delete-all-user-files)
(logout)
'x))
-- JonL --
∂24-Jun-88 1819 Common-Lisp-mailer Re: #.
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 24 Jun 88 18:16:45 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA03073; Fri, 24 Jun 88 18:14:40 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA26600; Fri, 24 Jun 88 18:10:34 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA09741; Fri, 24 Jun 88 18:17:23 PDT
Date: Fri, 24 Jun 88 18:17:23 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8806250117.AA09741@clam.sun.com>
To: edsel!jonl@labrea.stanford.edu
Subject: Re: #.
Cc: ELIOT@cs.umass.edu, Moon@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
> Thus while #. could be viewed as an adequate escape mechanism, it certainly
> couldn't be part of a general interchange language.
I have no very strong objections to special syntax for hash tables.
The same argument for special syntax does apply to other objects
including pathnames (for which Lucid (+ others) have the #P syntax),
readtables, and random-states. Really, there is a need for users to
be able to define their own types, *including* syntax for reading them
in. Once I start thinking of user-defined syntax, #. starts looking
more attractive again.
-Cris
∂25-Jun-88 1126 Common-Lisp-mailer Source code analysis tools
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Jun 88 11:26:45 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 424628; Sat 25-Jun-88 14:26:28 EDT
Date: Sat, 25 Jun 88 14:26 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Source code analysis tools
To: Common-Lisp@SAIL.STANFORD.EDU
File-References: AI.AI.MIT.EDU: MOON; ANNOTA >, AI.AI.MIT.EDU: MOON; MAPFOR >,
AI.AI.MIT.EDU: MOON; MAPFEX >, AI.AI.MIT.EDU: MOON; SUBST >,
AI.AI.MIT.EDU: MOON; TEMPLA >
Message-ID: <19880625182620.5.MOON@EUPHRATES.SCRC.Symbolics.COM>
Recently there have been some renewed inquiries about the source code
analysis tools I wrote five years ago. I've reconstructed these as best
I was able and placed them in the files referenced in the header of
this message. These files can be retrieved by anonymous FTP.
These tools are freely available to anyone and can be used for any
purpose. For example, Symbolics have incorporated an improved version
of the tools into their product. You can port these into any Common
Lisp that has LOOP if you tweak a few things. They are missing full
support for lexical scoping (principally FLET) and stylistically suffer
from excessive attention to minimization of consing. However they may
be useful as a guidepost or as a source of ideas. Certainly the
interface is more worthwhile than the implementation.
I regret that I cannot provide any support or documentation (beyond what
is included in the files themselves) for these tools. They are provided
as-is and I have not even tested them. I'll answer a reasonable number
of questions, if sent by electronic mail, as best I can.
∂27-Jun-88 1138 Common-Lisp-mailer Issue: STACK-LET (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jun 88 11:38:03 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 425330; 27 Jun 88 14:37:47 EDT
Date: Mon, 27 Jun 88 14:37 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: STACK-LET (Version 1)
To: Common-Lisp@SAIL.Stanford.EDU
Message-ID: <880627143734.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Issue: STACK-LET
References: None
Category: ADDITION
Edit history: 27-Jun-88, Version 1 by Pitman
Related-Issues: REST-ARGUMENT-EXTENT
Status: For Internal Discussion
Problem Description:
Sometimes a programmers knows that a particular data structure
will have only dynamic extent. In some implementations, it is
possible to allocate such structures in a way that will make them
easier to reclaim than by general purpose garbage collection
(eg, on the stack or in some temporary area). Currently, however,
there is no way to request the use of such an allocation mechanism.
Proposal (STACK-LET:NEW-MACROS):
Introduce the new macros:
STACK-LET bindings &BODY forms [Macro]
STACK-LET* bindings &BODY forms [Macro]
Like LET and LET*, but the objects which are the initial
values of the variables in the binding list have only
dynamic extent.
For each initial binding, the form is macroexpanded (as if
by MACROEXPAND-1) until either no further macro expansion is
possible or a form which is recognized by STACK-LET is seen.
For example:
(CONS x y) permits STACK-LET to allocate a cons on the stack.
(LIST x y z) permits STACK-LET to allocate a list on the stack.
(LIST* x y z) permits the first two conses of the resulting
list to be allocated on the stack.
(MAKE-ARRAY ...) permits an array to be allocated on the stack.
(MAKE-xxx ...) where MAKE-xxx is a defstruct constructor permits
the structure type to be allocated on the stack.
Note that an initial value form of (LIST X Y) is not the same
as (CONS X (LIST Y)) since STACK-LET may arrange for two cells
of the former to be stack-allocated, and only one cell of the
latter (the one created by CONS).
Note further that in (LIST (LIST 1 2) 3), only the top level
list (the one containing a cons and 3) may be stack allocated.
The list (1 2) must be allocated normally.
It is always permissible for STACK-LET to behave like LET.
Its use is merely advice to an implementation about the use
of a variable which might not otherwise be provable.
Test Case:
(STACK-LET ((X (LIST 1 2 3)))
(PRINT X)
NIL)
prints (1 2 3)
Rationale:
It permits a programmer to offer advice to an implementation about
what may be stack-allocated for efficiency.
It may be difficult or impossible for a compiler to infer this
same information statically.
Since a number of implementations offer this capability and there
is demand from users for access to the capability, this ``codifies
existing practice.''
Current Practice:
Symbolics Genera and Symbolics Cloe offer this extension.
Cost to Implementors:
No cost is forced since implementations are permitted to treat
STACK-LET and STACK-LET* as LET and LET*, respectively.
Cost to Users:
None. This change is upward compatible.
Cost of Non-Adoption:
Some portable code would be forced to run more slowly (due to
GC overhead), or to use non-portable primitives.
Benefits:
The cost of non-adoption is avoided.
Aesthetics:
This primitive allows a fairly low level optimization to work
by asking the user to provide only very high level information.
The alternatives (sharpsign conditionals, some of which may
lead to more bit-picky abstractions) are far less aesthetic.
Discussion:
It would also be possible to unify this proposal with
REST-ARGUMENT-EXTENT. The technique would be to allow
(LET ((X (LIST ...)))
(DECLARE (DYNAMIC-EXTENT X))
...)
to be rewritten by the compiler as:
(SYSTEM::STACK-LET ((X (LIST ...)))
...)
for example.
Pitman supports the STACK-LET:NEW-MACROS.
A better name might be chosen, but since some existing dialects
use this name, the name STACK-LET was suggested in an attempt to
not be gratuitously incompatible. (Also, the name DYNAMIC-LET,
which might seem more intuitive, is in use in other dialects to
mean that a dynamic variable is being bound, not that a lexical
variable is being bound to a dynamic object. It might, therefore,
be confusing to recycle that name here.)
∂27-Jun-88 1242 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
Received: from SEF1.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 27 Jun 88 12:42:12 PDT
Received: from SEF1.SLISP.CS.CMU.EDU by SEF1.SLISP.CS.CMU.EDU; 27 Jun 88 15:40:52 EDT
To: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
cc: Common-Lisp@SAIL.Stanford.EDU
Subject: Re: Issue: STACK-LET (Version 1)
In-reply-to: Your message of Mon, 27 Jun 88 14:37:00 -0400.
<880627143734.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Mon, 27 Jun 88 15:40:27 EDT
From: Scott.Fahlman@B.GP.CS.CMU.EDU
Is there any reason, aside from compatibility with the current Symbolics
usage, why you prefer
(stack-let ((x (list a b c))) ...body ...)
to
(let ((x (list a b c)))
(declare (dynamic-value x))
... body )
Since the idea is to give advice to the compiler about a specific binding,
it seems to me that a declaration would be more consistent with the rest of
the language than a new special form. For example, that's how we handle
advice about type restrictions. Also, this would allow one to mix dynamic
and non-dynamic bindings in the same LET form.
-- Scott
∂27-Jun-88 1306 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 27 Jun 88 13:05:55 PDT
Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 425412; Mon 27-Jun-88 16:04:37 EDT
Date: Mon, 27 Jun 88 16:04 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Issue: STACK-LET (Version 1)
To: Scott.Fahlman@B.GP.CS.CMU.EDU
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, Common-Lisp@SAIL.Stanford.EDU
In-Reply-To: The message of 27 Jun 88 15:40 EDT from Scott.Fahlman@B.GP.CS.CMU.EDU
Message-ID: <880627160423.1.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Date: Mon, 27 Jun 88 15:40:27 EDT
From: Scott.Fahlman@B.GP.CS.CMU.EDU
Is there any reason, aside from compatibility with the current Symbolics
usage,
Moon has our vote, not me. I usually leave it to him to evaluate what is good
or bad for Symbolics as a company. The extent to which Symbolics usage plays into
this is neither more or less than the extent to which any company offering this
primitive plays into this.
why you prefer
(stack-let ((x (list a b c))) ...body ...)
to
(let ((x (list a b c)))
(declare (dynamic-value x))
... body )
Since the idea is to give advice to the compiler about a specific binding,
it seems to me that a declaration would be more consistent with the rest of
the language than a new special form. For example, that's how we handle
advice about type restrictions. Also, this would allow one to mix dynamic
and non-dynamic bindings in the same LET form.
-- Scott
No really big reason. A couple of little reasons.
* In implementations where a related facility (eg, Zetalisp's older
WITH-STACK-LIST and WITH-STACK-LIST* primitives) exists, it's easy to
write a macro to translate STACK-LET into the other stuff. Whether it's
easy to add a declaration depends on how declarations are implemented.
* Since some implementations provide STACK-LET and not the modified LET, I
thought I'd get stronger support from people who do provide it. People
always seem to be more likely to vote for things that involve the least
work on their own part.
* I was afraid that some people would see this as a hairing up of LET.
In retrospect, however, I guess you're right. It could be useful for
DO, PROG, etc. if you had the declaration. Note well, however, that it's
not useful for any case where the construction form is not lexically
apparent to the binding form. Eg,
(DEFUN F (X) (DECLARE (DYNAMIC-EXTENT X)) ...)
would violate modularity boundaries to optimize
(F (LIST 1 2 3))
although I suppose some argument could be made that in block compilation
it was ok. By putting it in a STACK-LET form, this issue is made to not
come up.
* I sometimes get more results by suggesting something overly conservative
and letting people suggest that it's not right or not enough than I do by
suggesting originally the thing in full blown form. The latter strategy
often gets me not taken seriously, whereas the first strategy offers a
foot in the door to people who readily grasp the concepts of the stripped
down proposal and who might after admitting the topic for discussion still
arrive at the same position as I'd have originally wanted to propose.
In fact, the modified LET is fine with me. My main criterion is to have
something which has the highest likelihood of a yes vote in X3J13.
∂27-Jun-88 1338 Common-Lisp-mailer Issue: STACK-LET (Version 1)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 27 Jun 88 13:38:24 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA01974; Mon, 27 Jun 88 13:36:34 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA28150; Mon, 27 Jun 88 13:32:21 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA21955; Mon, 27 Jun 88 13:38:40 PDT
Date: Mon, 27 Jun 88 13:38:40 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8806272038.AA21955@lukasiewicz.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: Common-Lisp@SAIL.Stanford.EDU
In-Reply-To: Kent M Pitman's message of Mon, 27 Jun 88 14:37 EDT <880627143734.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM>
Subject: Issue: STACK-LET (Version 1)
...
It is always permissible for STACK-LET to behave like LET.
Its use is merely advice to an implementation about the use
of a variable which might not otherwise be provable.
...
It would also be possible to unify this proposal with
REST-ARGUMENT-EXTENT. The technique would be to allow
(LET ((X (LIST ...)))
(DECLARE (DYNAMIC-EXTENT X))
...)
to be rewritten by the compiler as:
(SYSTEM::STACK-LET ((X (LIST ...)))
...)
for example.
The DYNAMIC-EXTENT declaration is a smaller, cleaner addition
than a new STACK-LET special form.
It's less of a burden on implementors and users to ignore a declaration
than to expand one special form into another.
-- John
∂27-Jun-88 1547 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 27 Jun 88 15:47:44 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA04567; Mon, 27 Jun 88 15:46:13 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA03142; Mon, 27 Jun 88 15:41:54 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA11771; Mon, 27 Jun 88 15:48:53 PDT
Date: Mon, 27 Jun 88 15:48:53 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8806272248.AA11771@clam.sun.com>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Subject: Re: Issue: STACK-LET (Version 1)
Cc: Common-Lisp@SAIL.Stanford.EDU
> * I sometimes get more results by suggesting something overly conservative
> and letting people suggest that it's not right or not enough than I do by
> suggesting originally the thing in full blown form. The latter strategy
> often gets me not taken seriously, whereas the first strategy offers a
> foot in the door to people who readily grasp the concepts of the stripped
> down proposal and who might after admitting the topic for discussion still
> arrive at the same position as I'd have originally wanted to propose.
Whoah up, here. We'd better watch what we do, or we could get into
a nontechnical intellectual discussion here. (Thanks Kent for the thoughts.)
-Cris
∂28-Jun-88 1150 Common-Lisp-mailer please subscribe this worthless person to the mail list...
Received: from msr.epm.ornl.gov (MILNETH.ORNL.GOV) by SAIL.Stanford.EDU with TCP; 28 Jun 88 11:50:50 PDT
Received: by msr.epm.ornl.gov (5.51/4.9)
id AA16545; Tue, 28 Jun 88 14:50:18 EDT
Date: Tue, 28 Jun 88 14:50:18 EDT
From: pjo@msr.EPM.ORNL.GOV (Pedro Otaduy)
Message-Id: <8806281850.AA16545@msr.epm.ornl.gov>
To: common-lisp@sail.stanford.edu
Subject: please subscribe this worthless person to the mail list...
thanks!
∂28-Jun-88 1804 Common-Lisp-mailer #.
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 28 Jun 88 18:01:40 PDT
Received: by labrea.stanford.edu; Tue, 28 Jun 88 17:59:02 PDT
Received: from bhopal.lucid.com by edsel id AA08970g; Tue, 28 Jun 88 17:46:02 PDT
Received: by bhopal id AA09433g; Tue, 28 Jun 88 17:52:16 PDT
Date: Tue, 28 Jun 88 17:52:16 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806290052.AA09433@bhopal.lucid.com>
To: cperdue@sun.com
Cc: ELIOT@cs.umass.edu, Moon@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
In-Reply-To: Cris Perdue's message of Fri, 24 Jun 88 18:17:23 PDT <8806250117.AA09741@clam.sun.com>
Subject: #.
re: . . . Really, there is a need for users to able to define their own
types, *including* syntax for reading them in. Once I start thinking of
user-defined syntax, #. starts looking more attractive again.
I.e., as a "cop out"? Shades of YACC and LEX!
-- JonL --
∂28-Jun-88 2239 Common-Lisp-mailer Issue: STACK-LET (Version 1)
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 28 Jun 88 22:39:48 PDT
Received: by labrea.stanford.edu; Tue, 28 Jun 88 22:39:17 PDT
Received: from bhopal.lucid.com by edsel id AA10285g; Tue, 28 Jun 88 22:24:31 PDT
Received: by bhopal id AA11440g; Tue, 28 Jun 88 22:30:47 PDT
Date: Tue, 28 Jun 88 22:30:47 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806290530.AA11440@bhopal.lucid.com>
To: jrose@sun.com
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: John Rose's message of Mon, 27 Jun 88 13:38:40 PDT <8806272038.AA21955@lukasiewicz.sun.com>
Subject: Issue: STACK-LET (Version 1)
re: The DYNAMIC-EXTENT declaration is a smaller, cleaner addition
than a new STACK-LET special form.
It's less of a burden on implementors and users to ignore a declaration
than to expand one special form into another.
It was for just such reasons that Lucid chose (about one year ago) to
use a DYNAMIC-EXTENT declaration rather than specialized "stack list"
primtives, when implementing "stack list consing" for &rest arguments.
The suggestion is entertained to extend it to more contexts, such as
any LAMBDA-binding (or LET-binding if you must) where the value is
something that would have to be "consed up" afresh.
-- JonL --
∂30-Jun-88 0803 Common-Lisp-mailer EQUAL
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 30 Jun 88 08:03:16 PDT
Received: by labrea.stanford.edu; Thu, 30 Jun 88 08:02:46 PDT
Received: from bhopal.lucid.com by edsel id AA14691g; Wed, 29 Jun 88 18:44:42 PDT
Received: by bhopal id AA15550g; Wed, 29 Jun 88 18:50:58 PDT
Date: Wed, 29 Jun 88 18:50:58 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806300150.AA15550@bhopal.lucid.com>
To: edsel!jlm@labrea.stanford.edu
Cc: common-lisp@sail.stanford.edu, cl-cleanup@sail.stanford.edu
In-Reply-To: Jim McDonald's message of Fri, 24 Jun 88 16:40:01 EST <8806242339.AA18154@bhopal.lucid.com>
Subject: EQUAL
Date: Fri, 24 Jun 88 16:40:01 EST
From: Jim McDonald <jlm>
My concern about having EQUAL descend structures and arrays is that
they are much more likely than lists to be circular.
...
As a rule of thumb, I'd bet that less than .0001% of all lists are
circular, and that less than 1% of all arrays are circular, but only
that less than 30% of all structures are circular.
Probabilities can be very misleading here -- for any given application,
the probability is typically either 0 or 1. And even for those cases
that do utilize circular stucture (I'm including lists here), the
relevance to the EQUAL question is entirely moot if they are never
given as arguments to EQUAL. One would surely suspect that to be the
case for the many programs that deal in circular lists!
-- JonL --
∂30-Jun-88 0804 Common-Lisp-mailer [Re: EQUAL]
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 30 Jun 88 08:03:59 PDT
Received: by labrea.stanford.edu; Thu, 30 Jun 88 08:03:29 PDT
Received: from bhopal.lucid.com by edsel id AA14758g; Wed, 29 Jun 88 18:50:50 PDT
Received: by bhopal id AA15565g; Wed, 29 Jun 88 18:57:09 PDT
Date: Wed, 29 Jun 88 18:57:09 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8806300157.AA15565@bhopal.lucid.com>
To: goldman@vaxa.isi.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: goldman@vaxa.isi.edu's message of Fri, 24 Jun 88 18:15:43 PDT <8806250115.AA22390@vaxa.isi.edu>
Subject: [Re: EQUAL]
[Neil, I'm cc'ing my reply to the whole list, since I think you questions
are of general relevance. Apologies in advance if you really didn't want
to "go public" with your question. -- JonL --]
From: goldman@vaxa.isi.edu
Date: Fri, 24 Jun 88 18:15:43 PDT
. . .
(2) Descend defstructs, except possibly for "system" defstructs ...
What are potential "system" defstructs? Is the phrase limited to the list
of types on page 13? If so, then it sounds ok, since EQUAL is already
(independently) appropriately defined on BIGNUMS and PATHNAMES. But it
just says "such as ..." on page 13, which leaves some doubt.
I was certainly thinking of those types on page 13, since they are the
ones addressed by the "cleanup" issue "type-hierarchy-underspecfied".
(3) Require that EQUAL be a "generic" function, so that CLOS methods
can be written for it, likely, the "default" method for non-built-in
classes would be some sort of error, meaning that mindless descent
isn't a good default.
First, I would think that (OBJECT OBJECT) would have an EQUAL method
that applied EQL, not ERROR, and that method would inherit to all standard
classes under OBJECT. I must misunderstand your intent -- you certainly
would want EQUAL to be TRUE whenever EQ was true, not an error?
I'm not 100% certain that one would want this. Perhaps the CLOS subcommittee
of x3j13 will tackle it. Mostly, the default method is just to say that
you shouldn't be doing this (calling EQUAL) on an object of this type. But
just having no applicable method may in fact be a better kind of error. Of
course, a default method could check for EQ before causing any other kind of
error.
If programmers to extend EQUAL in CLOS style -- which means
with arbitrary procedural definitions for their new classes -- could
EQUAL hash tables be implemented efficiently? How would they hash
values belonging to the new classes?
As you pointed out in subsequent discussion, a user-supplied EQUAL method,
whether for CLOS classes or as a defstruct option, leaves open the question
of mechanically verifying that the alleged predicate is reflexive, symmetric,
and transitive. Another major problem with using hash-tables on objects
with non-default EQUAL methods is that the SXHASH function must be similarly
extended for these data types; SXHASH must obey the property that
(equal x y) imples (= (sxhash x) (sxhash x))
See CLtL p285. At one time, there was a suggestion that hash tables admit
a user-supplied equivalence predicate; but it never got very far for just
this reason, that the equivalence predicate must be *** paired up** with an
appropriate "numericalizer" function, and many implementors felt that users
wouldn't understand these issues and wouldn't be able to construct up their
own versions of sxhash to go with their alleged equivalence predicates.
[SXHASH is required to be "good enough" for the EQUAL equivalence releation,
and for subsets of that relation such as STRING=, but it is unlikely that
any vendor makes it "good enough" for, say, EQUALP. Lucid has EQUALP hash
tables, but they don't use SXHASH.]
. . .
[Pardon me if I am impuning more to your suggestion than you intended.
This discussion that started on the meaning of DEFCONSTANT and QUOTE has
spread out quite a bit, and maybe you are just suggesting this as
an improvement to EQUAL with no implications about it clarifying
defconstant/quote].
Yes, the Subject line of this interchange has been "EQUAL" -- not
"constant folding/smashing" as before. Jim MacDonald was simply
inspired by the defconstant/quote issue to open up the EQUAL one.
-- JonL --
∂30-Jun-88 1241 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 30 Jun 88 12:41:10 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA14063; Thu, 30 Jun 88 12:38:47 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA24101; Thu, 30 Jun 88 12:34:26 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA01804; Thu, 30 Jun 88 12:40:54 PDT
Date: Thu, 30 Jun 88 12:40:54 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8806301940.AA01804@lukasiewicz.sun.com>
To: edsel!jonl@labrea.stanford.edu
Cc: goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Wed, 29 Jun 88 18:57:09 PDT <8806300157.AA15565@bhopal.lucid.com>
Subject: EQUAL, and hash tables, and value/object distinctions
Two remarks on EQUAL and hash tables, from a hash table fan.
First, if EQUAL is going to descend structures and arrays to test
for isomorphism, it should compare hash tables for equality
according to their contents. That is, it should verify
that two possibly-equal hash tables have the same set of
keys, and that for each key the two stored values are EQUAL.
Key equality testing must be done using each table's
key comparison function.
[Rationale & discussion are below, on the next page.
But first I've got to respond to something else.]
Date: Wed, 29 Jun 88 18:57:09 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
From: goldman@vaxa.isi.edu
Date: Fri, 24 Jun 88 18:15:43 PDT
...
If programmers to extend EQUAL in CLOS style -- which means
with arbitrary procedural definitions for their new classes -- could
EQUAL hash tables be implemented efficiently? How would they hash
values belonging to the new classes?
As you pointed out in subsequent discussion, a user-supplied EQUAL method,
whether for CLOS classes or as a defstruct option, leaves open the question
of mechanically verifying that the alleged predicate is reflexive, symmetric,
and transitive. Another major problem with using hash-tables on objects
with non-default EQUAL methods is that the SXHASH function must be similarly
extended for these data types; SXHASH must obey the property that
(equal x y) imples (= (sxhash x) (sxhash x))
See CLtL p285. At one time, there was a suggestion that hash tables admit
a user-supplied equivalence predicate; but it never got very far for just
this reason, that the equivalence predicate must be *** paired up** with an
appropriate "numericalizer" function, and many implementors felt that users
wouldn't understand these issues and wouldn't be able to construct up their
own versions of sxhash to go with their alleged equivalence predicates.
Yuck. Who are these brilliant Implementors, that we may all worship
at their feet? For they are the curators of such profound knowledge as
(EQUALITY-PREDICATE X Y) ==> (= (HASH-FN X) (HASH-FN Y))
If we mere Users cannot be trusted with such wisdom, how are we to
navigate the Streams of Extensibility, or handle the Objects of
Genericity? Oh great Implementors, save us, we pray, from overmuch
functionality.
Seriously, I hear an alarming amount of condescension in the above reasoning.
The above logical implication is ALL THAT IS NEEDED to construct an
appropriate hash function. It is the sole and fundamental insight which
makes hash tables work; I have relied on it for years, building many a
hash table in various extensible frameworks. What's the problem of
requiring a hash-table builder from promising that his hash and equality
functions bear the simple relation to each other? And if he can't
handle that, what chance does he have of building a working stream type,
or making sense out of CLOS? (Note that many vendors have supplied more
or less hairy stream definition facilities, which usually require
invariants much more complex than the hash invariant above.)
As for "mechanical verification" of the hashing and equality invariants,
that's a red herring. Since when do we mechanically verify any of the
required properties of functional arguments to Lisp primitives? (I'm
thinking particularly of the :KEY and :TEST arguments to sequence
functions.) Just say that unless the supplied functions satisfy the
required conditions "it is an error".
The "pairing up" of equality and hashing could be done cleanly in CLOS
by defining generic equality and hashing methods for particular hash
table types.
[SXHASH is required to be "good enough" for the EQUAL equivalence releation,
and for subsets of that relation such as STRING=, but it is unlikely that
any vendor makes it "good enough" for, say, EQUALP. Lucid has EQUALP hash
tables, but they don't use SXHASH.]
-- JonL --
!
Proposal: EQUAL should check for isomorphism of hash tables.
The effect of this rule is to treat hash tables like lists,
structures, and arrays for equality testing, under the following
reasonable theory of the semantics of lists, structures, arrays,
and hash tables: The meaning of any such data structure is
determined by a small set of (call them) "access keys" and
a value stored under each access key. The set of access
keys for each kind of data structure is {CAR,CDR}, a set of
slot access functions, an initial setquence of non-negative integers,
and a set of Lisp objects, respectively.
Other than the differences in these "access keys", all four
of the above data structures are tuple types, in that they
store a finite set of values, each accessible under its own
key. An equality function which performs an isomorphism check
on any of those tuple types should perform it on all of them,
or have a very specific reason not to.
If two hash tables differ not in their contents but in their
implementation parameters (such as size or equality function),
we must choose whether to compare structure abstractly
(looking only at contents) or concretely (looking also
at implementation parameters). This question comes up
with respect to array structural equality also. For
example, do we allow a fill pointer to define an array's
length (i.e., its "access key" set), or do we look at
the length of the underlying allocated storage? What
about comparing an (array t) having a fill pointer,
with a string? I believe the people working on this
problem will come to a more or less abstract viewpoint,
and if so, that viewpoint should be applied consistently
to hash tables.
An interesting question arises when two hash tables have
different key equality predicates, and (suppose) we've already
decided to treat equality predicates as implementation details,
and ignore them directly. Here's one answer: Declare two
hash tables EQUAL if they include each other. That is, for
every key K in hash table A, require that
(EQUAL (GETHASH A K) (GETHASH B K *UNIQUE-UNKNOWN-VALUE*))
and the same for every key in table B.
Possible specific reasons not to test for hash table isomorphism,
with comments or rebuttals in brackets:
(1) It's too hard to implement.
[No, it's actually pretty easy to implement this test
portably using a MAPHASH over each table; each MAPHASH
tests one direction of inclusion by performing
GETHASHs.]
(2) It's too slow to implement.
[Any recursive descent takes a long time to do.
But hash tables can probably be made faster to compare
than corresponding CONS structures, because they can use
saved key hash values to advantages. A hash table's
key set can be hashed by combining all its key hash
values.]
(3) Recursive descent into hash tables is too unexpected.
[For programmers unfamiliar with hash tables, many of
their properties are going to be pretty surprising.
Programmers who understand their nature and use are
also going to understand their correspondence with
lists, structures, and (especially) arrays; it is
these programmers whose expectations we should design for.]
(4) Hash tables are different because we expect frequent
side effects on them, and so momentary isomorphism
between two of them is not significant.
[This is the best argument against, I think. See below.]
About (4): Cons cells, structures, arrays, and hash tables can all be
used either as pure values (that is, no updates after initial
construction, and object identity is not important) or as updatable
objects (updates are expected, and shared object identities are
crucial). Under current Lisp practice, hash tables are rarely used
as pure values. (Cons cells usually are, and structures and arrays
occasionally are.)
We may call types which are used as pure values "value-like"
and types which are used as shared objects "object-like".
Notice that EQUAL and EQL differ in their theory of cons cells: EQUAL
treats them as pure values, and EQL as sharable objects. I believe
a consistent way of accounting for this is to say that the behavior
of EQUAL and EQL differ for types which have this dual nature,
of value-like and object-like. (For types which are only value-like,
such as complex numbers, EQL compares substructures, just as EQUAL
does. For types which are only object-like, such as streams,
EQUAL compares object identity, just as EQL does.)
So, if you believe all that about EQUAL and EQL, the question of EQUAL
on hash tables gets down to this: Are hash tables so object-like that
no one is likely to think of them as pure values?
Consider this: Hash tables can be used to implement sets,
if you need to optimize the speed of the set-inclusion operator.
Sets are value-like types. Hash tables can be used to implement
finite functions; if they themselves are hashable and comparable,
one can build higher-order functional systems out of them
(and get memoization as a bonus).
-- John
∂30-Jun-88 1340 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Jun 88 13:40:04 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 427334; Thu 30-Jun-88 16:36:56 EDT
Date: Thu, 30 Jun 88 16:36 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
To: jrose@Sun.COM, edsel!jonl@labrea.stanford.edu
cc: goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8806301940.AA01804@lukasiewicz.sun.com>
Message-ID: <19880630203650.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Thu, 30 Jun 88 12:40:54 PDT
From: jrose@Sun.COM (John Rose)
Two remarks on EQUAL and hash tables, from a hash table fan.
...
Date: Wed, 29 Jun 88 18:57:09 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
As you pointed out in subsequent discussion, a user-supplied EQUAL method,
whether for CLOS classes or as a defstruct option, leaves open the question
of mechanically verifying that the alleged predicate is reflexive, symmetric,
and transitive. Another major problem with using hash-tables on objects
with non-default EQUAL methods is that the SXHASH function must be similarly
extended for these data types; SXHASH must obey the property that
(equal x y) imples (= (sxhash x) (sxhash x))
See CLtL p285. At one time, there was a suggestion that hash tables admit
a user-supplied equivalence predicate; but it never got very far for just
this reason, that the equivalence predicate must be *** paired up** with an
appropriate "numericalizer" function, and many implementors felt that users
wouldn't understand these issues and wouldn't be able to construct up their
own versions of sxhash to go with their alleged equivalence predicates.
Yuck. Who are these brilliant Implementors, that we may all worship
at their feet? For they are the curators of such profound knowledge as
(EQUALITY-PREDICATE X Y) ==> (= (HASH-FN X) (HASH-FN Y))
Yes, but the equality-predicate must be transitive over the domain of
possible keys in order for a hash-function to work.
For example, one cannot construct a hash-function for #'= unless you limit
the valid keys to not include both a floating point number and two
integers that both coerce to that same float.
(i.e.
(let* ((a (expt 2 56))
(b (1+ a))
(c (float a)))
(values (= a b) (= a c) (= b c)))
=> NIL T T
)
I'm not voting for condescension, nor for protecting programmers from
themselves. I just want to point out that it is slightly more
complicated than you make it seem.
My personal opinion is that CLtL should have allowed both the predicate
and hash-function to be defined once it included hash tables in the
language spec. In a real application the programmer will probably want
to construct a custom hash function anyway, even for :TEST 'EQ. If the
table has a known, or typical, set of keys, that might allow a much more
efficient, or more collision-free, hash function.
Hash tables aren't so complicated that one can't construct them
yourself. My guess (and only a guess) is that the only reason they're
included in the language spec is to give a portable way of hashing on
%pointer where that might be useful. SXHASH would have been enough, and
that allows easy implementation of the common case of EQUAL hash tables,
too.
The minimalist in me still wonders why hash tables were included in
CLtL.
Seriously, I hear an alarming amount of condescension in the above reasoning.
The above logical implication is ALL THAT IS NEEDED to construct an
appropriate hash function. It is the sole and fundamental insight which
makes hash tables work; I have relied on it for years, building many a
hash table in various extensible frameworks. What's the problem of
requiring a hash-table builder from promising that his hash and equality
functions bear the simple relation to each other? And if he can't
handle that, what chance does he have of building a working stream type,
or making sense out of CLOS? (Note that many vendors have supplied more
or less hairy stream definition facilities, which usually require
invariants much more complex than the hash invariant above.)
∂30-Jun-88 1438 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 30 Jun 88 14:38:31 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA01182; Thu, 30 Jun 88 14:36:25 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA27554; Thu, 30 Jun 88 14:32:01 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA01962; Thu, 30 Jun 88 14:38:29 PDT
Date: Thu, 30 Jun 88 14:38:29 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8806302138.AA01962@lukasiewicz.sun.com>
To: Greenwald@STONY-BROOK.SCRC.Symbolics.COM
Cc: edsel!jonl@labrea.stanford.edu, goldman@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Thu, 30 Jun 88 16:36 EDT <19880630203650.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
Date: Thu, 30 Jun 88 16:36 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Date: Thu, 30 Jun 88 12:40:54 PDT
From: jrose@Sun.COM (John Rose)
Two remarks on EQUAL and hash tables, from a hash table fan.
...
Date: Wed, 29 Jun 88 18:57:09 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
As you pointed out in subsequent discussion, a user-supplied EQUAL method,
whether for CLOS classes or as a defstruct option, leaves open the question
of mechanically verifying that the alleged predicate is reflexive, symmetric,
and transitive.
...
[Flame from Rose...]
(EQUALITY-PREDICATE X Y) ==> (= (HASH-FN X) (HASH-FN Y))
Yes, but the equality-predicate must be transitive over the domain of
possible keys in order for a hash-function to work.
For example, one cannot construct a hash-function for #'= unless you limit
the valid keys to not include both a floating point number and two
integers that both coerce to that same float.
(i.e.
(let* ((a (expt 2 56))
(b (1+ a))
(c (float a)))
(values (= a b) (= a c) (= b c)))
=> NIL T T
)
I'm not voting for condescension, nor for protecting programmers from
themselves. I just want to point out that it is slightly more
complicated than you make it seem.
Well, for the record, I'll try not to gloss over the fact that the
EQUALITY-PREDICATE must be an equality predicate (:-). That is, it must
be reflexive, symmetric, and transitive. In my experience, equality
predicates are not difficult to write, and are verified by inspection,
so "reflexive, symmetric, and transitive" is not really a burden.
Writing a hash function takes a little more effort, since you've got to
make sure its structure accurately mirrors the equality predicate
you've already written.
Your point about #'= and domains is well taken. I had forgotten
about the CL numeric conversions. I think the general principle
here is that if you're comparing equality over domains inside
of which there are implicit conversions that lose information,
equality testing and hashing should be performed in such a way that
the information is reliably thrown out, or reliably retained.
(And these two choices yield key domains of different granularities.)
For example, a hash table over real numbers including floats might
use one of these equality predicates instead of #'=:
;; Coarser grain:
#'(lambda (x y) (= (float x 0L0) (float y 0L0)))
;; Finer grain:
#'(lambda (x y) (= (rational x) (rational y)))
-- John
∂30-Jun-88 2256 Common-Lisp-mailer Re: Issue: STACK-LET (Version 1)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 30 Jun 88 22:56:21 PDT
Received: from Burger.ms by ArpaGateway.ms ; 30 JUN 88 22:55:28 PDT
Sender: "Larry_Masinter.PARC"@Xerox.COM
Date: 30 Jun 88 22:54:22 PDT (Thursday)
Subject: Re: Issue: STACK-LET (Version 1)
From: masinter.PARC@Xerox.COM
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
cc: Scott.Fahlman@B.GP.CS.CMU.EDU, KMP@STONY-BROOK.SCRC.Symbolics.COM,
Common-Lisp@SAIL.Stanford.EDU
In-Reply-to: KMP%STONY-BROOK.SCRC.Symbolics:COM's message of Monday, June 27,
1988 1:53 pm
Reply-to: masinter.PARC@Xerox.COM
Message-ID: <880630-225528-6029@Xerox>
While I would like very much to find some way to express dynamic extent within
the language, I'm
unhappy with either (declare (dynamic-value ...)) or stack-let for two reasons:
a) it is disturbing to introduce a construct within which a casual change of
(CONS X (LIST Y Z)) to
(LIST X Y Z) could introduce a serious bug (e.g., if the tail were stashed away
somewhere.)
b) the construct really only allows dynamic extent on one-level structures . If
you wanted to
create a copy of (A (B C) (D E (F G)))
you would have to say something like
(stack-let* ((part2 (list 'b 'c)) (part3c (list 'f 'g)) (part3 (list 'd 'e
part3c)) ((whole-thing (list 'a part2 part3))) ...)
Your proposal did not mention objects other than lists; what of DEFSTRUCT or
CLOS instances?
∂01-Jul-88 1217 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 1 Jul 88 12:17:22 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 1 Jul 88 15:17:41 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 1 Jul 88 15:15:26 EDT
Date: Fri, 1 Jul 88 15:15 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
To: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
Cc: jrose@sun.com, edsel!jonl@labrea.stanford.edu, goldman@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <19880630203650.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Message-Id: <19880701191544.6.BARMAR@OCCAM.THINK.COM>
Date: Thu, 30 Jun 88 16:36 EDT
From: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
For example, one cannot construct a hash-function for #'= unless you limit
the valid keys to not include both a floating point number and two
integers that both coerce to that same float.
(i.e.
(let* ((a (expt 2 56))
(b (1+ a))
(c (float a)))
(values (= a b) (= a c) (= b c)))
=> NIL T T
)
Actually, it's not that difficult to construct such a hash function.
All it has to do is coerce its argument before hashing, e.g.
(defun =-hash (number)
(let ((real (realpart number))
(imag (imagpart number)))
(setq number (complex (coerce real 'long-float)
(coerce imag 'long-float))))
<compute the hash>)
I admit that this isn't a great hash function if you expect your keys to
include many bignums that are near each other. But it is guaranteed to
be a correct hash (assuming <compute the hash> is well behaved).
barmar
∂02-Jul-88 1146 Common-Lisp-mailer dynamic extent lisp objects
Received: from ucbvax.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 2 Jul 88 11:45:05 PDT
Received: by ucbvax.Berkeley.EDU (5.59/1.28)
id AA13200; Fri, 1 Jul 88 20:21:33 PDT
From: trwrb!smpvax1!jrg@ucbvax.Berkeley.EDU
Received: by trwrb (5.51/1.36)
id AA03450; Fri, 1 Jul 88 18:56:03 PDT
Date: Fri, 1 Jul 88 18:56:03 PDT
Message-Id: <8807020156.AA03450@trwrb>
To: common-lisp@sail.stanford.edu
Subject: dynamic extent lisp objects
Speaking as a representative from a company that has a reasonably
successful lisp-based software product, having the ability to declare an
object to have dynamic extent is of great benefit in building a
practical lisp-based product. I strongly support this addition to the
language. I prefer the declaration form for many of the same reasons
already mentioned by its other advocates. But I'd rather have either or
even some other syntax supporting similar functionality than nothing.
While I believe several of the other clean-up language changes are
beneficial and several of the proposed additions to the language are
useful, this is the first issue that I've been motivated to actively
support. Being able to use a feature such as this can be the difference
between having a practical product that many customers can use and
having one that is impossible to deploy in many, if not most,
environments.
--Joe Ginder
∂03-Jul-88 0956 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 3 Jul 88 09:56:25 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 428227; Sun 3-Jul-88 12:55:06 EDT
Date: Sun, 3 Jul 88 12:54 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
To: barmar@Think.COM, Greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: jrose@sun.com, edsel!jonl@labrea.stanford.edu, goldman@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-Reply-To: <19880701191544.6.BARMAR@OCCAM.THINK.COM>
Message-ID: <19880703165454.6.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Fri, 1 Jul 88 15:15 EDT
From: Barry Margolin <barmar@Think.COM>
Date: Thu, 30 Jun 88 16:36 EDT
From: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
For example, one cannot construct a hash-function for #'= unless you limit
the valid keys to not include both a floating point number and two
integers that both coerce to that same float.
(i.e.
(let* ((a (expt 2 56))
(b (1+ a))
(c (float a)))
(values (= a b) (= a c) (= b c)))
=> NIL T T
)
Actually, it's not that difficult to construct such a hash function.
All it has to do is coerce its argument before hashing, e.g.
I think you are confused. The problem isn't in having a valid
hash-function ( (DEFUN TRIVIAL-=-HASH (NUMBER) 1) is legal and valid,
but inefficient), the problem is which bucket you put a, b, and c in my
example above.
In other words, what does
(DEFUN TEST-BARMAR-HASH ()
(SETF (GETHASH a TABLE) 0)
(SETF (GETHASH b TABLE) 1)
(SETF (GETHASH c TABLE) 2)
(VALUES (GETHASH a TABLE) (GETHASH b TABLE) (GETHASH c TABLE)))
return?)
Unless you restrict the domain as specified above, you are in a
quandary. If you coerce them all to long-floats, then
(TEST-BARMAR-HASH) => 2,2,2
If you coerce them all to integers then (depending on the
implementation) you can get
(TEST-BARMAR-HASH) => 0,1,2 or 0,2,2 or 2,1,2
(defun =-hash (number)
(let ((real (realpart number))
(imag (imagpart number)))
(setq number (complex (coerce real 'long-float)
(coerce imag 'long-float))))
<compute the hash>)
I admit that this isn't a great hash function if you expect your keys to
include many bignums that are near each other. But it is guaranteed to
be a correct hash (assuming <compute the hash> is well behaved).
The hash isn't a problem. It's the fact that #'= isn't transitive.
barmar
∂03-Jul-88 1510 Common-Lisp-mailer Re: dynamic extent lisp objects
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 3 Jul 88 15:09:52 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA20651; Sun, 3 Jul 88 15:08:15 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA03866; Sun, 3 Jul 88 15:03:47 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA16720; Sun, 3 Jul 88 15:11:07 PDT
Date: Sun, 3 Jul 88 15:11:07 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8807032211.AA16720@clam.sun.com>
To: common-lisp@sail.stanford.edu, trwrb!smpvax1!jrg@ucbvax.Berkeley.EDU
Subject: Re: dynamic extent lisp objects
> Speaking as a representative from a company that has a reasonably
> successful lisp-based software product, having the ability to declare an
> object to have dynamic extent is of great benefit in building a
> practical lisp-based product.
How clear are you on the issue of whether a declaration facility
for variables would be adequate for your needs?
One can imagine a form named something like "with-dynamic-extent" that
causes all storage allocation "within" its body that would ordinarily
be done on the heap to be done on the stack instead.
My personal guess is that the variable declarations wind up being
more controllable, but that a "with" form would prove somewhat
more powerful. Certainly the "with" form could handle complex
backquotes easier than variable declarations could.
Any practical experience one way or the other?
-Cris
∂03-Jul-88 2356 Common-Lisp-mailer What have hashing and equality to do with each other?
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 3 Jul 88 23:56:23 PDT
Received: from BRAHMA.ACA.MCC.COM by MCC.COM with TCP/SMTP; Mon 4 Jul 88 01:55:55-CDT
Date: Mon, 4 Jul 88 01:55 CDT
From: David Vinayak Wallace <Gumby@MCC.COM>
Subject: What have hashing and equality to do with each other?
To: common-lisp@sail.stanford.edu
In-Reply-To: <19880703165454.6.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Message-ID: <880704015545.4.GUMBY@BRAHMA.ACA.MCC.COM>
There has been some discussion of hashing algorithms spawned by the
assertion that (= (compute-hash-index-for a) (compute-hash-index-for b))
is a sufficient definition of (equal a b). Nobody has said so, but "it
ain't so!"
The point of hashing is to map a large, sparse space into a smaller
(hopefully more) dense one. Once you compute a hash index you have to
peek into the table and look for a collision (what you do then is up to
you).
What's this rumour I heard about the CLOS people having defined EQUAL as
a generic function....
∂05-Jul-88 1749 Common-Lisp-mailer re: EQUAL, and hash tables, and value/object distinctions
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 5 Jul 88 17:49:08 PDT
Posted-Date: Tue, 05 Jul 88 17:49:37 PDT
Message-Id: <8807060049.AA21993@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA21993; Tue, 5 Jul 88 17:49:39 PDT
To: common-lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: re: EQUAL, and hash tables, and value/object distinctions
Date: Tue, 05 Jul 88 17:49:37 PDT
Sender: goldman@vaxa.isi.edu
Proposal: EQUAL should check for isomorphism of hash tables.
I think that's fine; the issue is what properties define, and thus derive
from, two hash tables being isomorphic.
An interesting question arises when two hash tables have
different key equality predicates, and (suppose) we've already
decided to treat equality predicates as implementation details,
and ignore them directly. Here's one answer: Declare two
hash tables EQUAL if they include each other. That is, for
every key K in hash table A, require that
(EQUAL (GETHASH A K) (GETHASH B K *UNIQUE-UNKNOWN-VALUE*))
and the same for every key in table B.
I definitely do not like that definition. I don't think that two
hash tables with different equality predicates should be considered
EQUAL unless they are both EMPTY.
Rationale: A hash table is best though of as a mapping from (a subset of) the
EQUIVALENCE CLASSES of an equivalence predicate to associated values.
The fact the CommonLisp's functions for dealing with hash tables
(GETHASH, MAPHASH) deal with an equivalence class through an exemplary
member of the class should not lead us astray. The suggested semantics, as
I read it, makes the issue of whether two hash tables are EQUAL dependent
on which exemplars happen to be stored.
For example, suppose HEQ and HEQUAL are hash tables, with equivalence
predicates EQ and EQUAL, respectively. Further suppose
(EQUAL xxx '(a b c)) and (EQUAL yyy '(a b c)) , but
(NOT (EQ xxx yyy))
if I do (setf (gethash xxx HEQ) 1 (gethash yyy HEQUAL) 1)
then, by my reading of the above definition,
(NOT (EQUAL HEQ HEQUAL))
because the key yyy, in HEQUAL, is not a key in HEQ. But if I do
(setf (gethash xxx HEQ) 1 (gethash xxx HEQUAL) 1)
then they are EQUAL. I claim that the choice between two different
exemplars of an E equivalence class should be transparent for a
hash table with equivalence predicate E.
I would define EQUALity of hash tables H1 and H2 in the following
manner:
either H1 and H2 are both empty, or
the suggested mutual inclusion definition, with the added requirment
that H1 and H2 have the same equivalence predicate.
Note that this does not imply that MAPHASH applied to the two tables will
generate the same sequence of key/value pairs -- the ordering used by
maphash is an implementation detail, and could even change from one
invocation to another on the same, unaltered, hash table.
Also, "it is an error" to destructively modify a value that has been used
as a key for a hashtable of equivalence E (or obtained via a MAPHASH
over such a hashtable) in a manner that changes the E-class to which it
belongs. I.e., the following is an incorrect program:
(setf h (make-hash-table :test 'equal)
xxx '(a b c))
(setf (gethash xxx h) 1)
(setf (second xxx) nil)
Neil
∂06-Jul-88 1344 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 6 Jul 88 13:44:22 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA09648; Wed, 6 Jul 88 13:42:20 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-3.2)
id AA26636; Wed, 6 Jul 88 13:37:43 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA24466; Wed, 6 Jul 88 13:44:31 PDT
Date: Wed, 6 Jul 88 13:44:31 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8807062044.AA24466@lukasiewicz.sun.com>
To: goldman@vaxa.isi.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: goldman@vaxa.isi.edu's message of Tue, 05 Jul 88 17:49:37 PDT <8807060049.AA21993@vaxa.isi.edu>
Subject: EQUAL, and hash tables, and value/object distinctions
Posted-Date: Tue, 05 Jul 88 17:49:37 PDT
From: goldman@vaxa.isi.edu
Date: Tue, 05 Jul 88 17:49:37 PDT
Sender: goldman@vaxa.isi.edu
Proposal: EQUAL should check for isomorphism of hash tables.
I think that's fine; the issue is what properties define, and thus derive
from, two hash tables being isomorphic.
An interesting question arises when two hash tables have
different key equality predicates, and (suppose) we've already
decided to treat equality predicates as implementation details,
and ignore them directly. Here's one answer: Declare two
hash tables EQUAL if they include each other. That is, for
every key K in hash table A, require that
(EQUAL (GETHASH A K) (GETHASH B K *UNIQUE-UNKNOWN-VALUE*))
and the same for every key in table B.
I definitely do not like that definition. I don't think that two
hash tables with different equality predicates should be considered
EQUAL unless they are both EMPTY.
Rationale: A hash table is best though of as a mapping from (a subset of) the
EQUIVALENCE CLASSES of an equivalence predicate to associated values.
Good rationale. OK, the "hash"-ness is abstracted away when
thinking about hash table semantics, and the equivalence class
structure should remain, abstracting away from the specific
keys. So a hash table is "really" a finite map over a set
of equivalence classes.
The fact the CommonLisp's functions for dealing with hash tables
(GETHASH, MAPHASH) deal with an equivalence class through an exemplary
member of the class should not lead us astray....
...
There's one sticky problem when we concentrate on equivalence
classes rather than exemplars: Equivalence classes are defined
via equivalence predicates, which in Lisp are algorithms.
So, if user-defined hash tables are ever supported,
we need to carefully design a notion of "same equivalence
predicate". Equivalence of algorithms is undecidable,
and so we need a narrower notion predicate equivalence.
(That's why I was trying to ignore the predicates altogether;
it finesses this problem.)
This isn't an issue yet, of course. EQ can distinguish
#'EQ, #'EQL, and #EQUAL.
Incidentally, what should happen to user-defined hash tables
when their predicates or hash functions are redefined?
There is a CLOS hook MAKE-INSTANCES-OBSOLETE which could
be used to re-construct all instances of the affected
table type.
Neil
-- John
∂06-Jul-88 1612 Common-Lisp-mailer [Re: EQUAL]
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 6 Jul 88 16:12:04 PDT
Posted-Date: Wed, 06 Jul 88 16:11:58 PDT
Message-Id: <8807062312.AA13550@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA13550; Wed, 6 Jul 88 16:12:07 PDT
To: edsel!jonl@labrea.stanford.edu
From: goldman@vaxa.isi.edu
Subject: [Re: EQUAL]
Cc: common-lisp@sail.stanford.edu
In-Reply-To: edsel!jonl@labrea.stanford.edu's message of 2792627829
Date: Wed, 06 Jul 88 16:11:58 PDT
Sender: goldman@vaxa.isi.edu
My original response to part of JonL's suggestion regarding CLOS and
EQUAL:
First, I would think that (OBJECT OBJECT) would have an EQUAL method
that applied EQL, not ERROR, and that method would inherit to all standard
classes under OBJECT. I must misunderstand your intent -- you certainly
would want EQUAL to be TRUE whenever EQ was true, not an error?
JonL's comment on that:
I'm not 100% certain that one would want this. Perhaps the CLOS subcommittee
of x3j13 will tackle it. Mostly, the default method is just to say that
you shouldn't be doing this (calling EQUAL) on an object of this type. But
just having no applicable method may in fact be a better kind of error. Of
course, a default method could check for EQ before causing any other kind of
error.
But because EQUAL is defined to recur to components of certain compound
objects, saying that it is an error to call EQUAL on objects of type C
implies that it would be an error to call it on compound objects (say,
lists) containing Cs. It seems wrong to me NOT to be able to choose to
represent something with a CLOS object if you want to use it in a list, or
array, or struct, that is going to tested with EQUAL.
I would feel far better if EQ, EQL, EQUAL, and EQUALP (the built-in
equivalence predicates) were well defined (no errors) over the entire
universe of lisp objects. This does not imply that one couldn't
make EQUAL a generic function; only that it would "be an error" to
write EQUAL methods that destroyed the properties of EQUAL that make it a
universal equivalence predicate. [Like, I'd be very suspicous
of any method with different specializers for the two arguments.]
Neil
∂08-Jul-88 1316 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 8 Jul 88 13:16:10 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Fri, 8 Jul 88 13:13:16 PDT
Date: Fri, 8 Jul 88 13:13:16 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <880708131316.2020021f@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: error handling
Date: Thu, 7-JUL-1988 13:50 MST
X-VMS-Mail-To: @COMMON-LISP
Can anyone tell me a good (portable) way to handle error handlers in
common lisp?
Steve Pothier
SAIC
5151 East Broadway, Suite 900
Tucson, AZ 85711-3796
602-748-7400
pothiers%tuva.sainet@nmfecc.arpa
∂11-Jul-88 1111 CL-Object-Oriented-Programming-mailer CLOS Workshop
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Jul 88 11:11:23 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 11 JUL 88 11:06:55 PDT
Date: Mon, 11 Jul 88 11:02 PDT
From: Gregor.pa@Xerox.COM
Reply-To: Gregor@GRAPEVINE.parc.xerox.com
Subject: CLOS Workshop
To: Common-Lisp@Sail.Stanford.edu, common-lisp-object-system@sail.stanford.edu,
CL-Object-Oriented-Programming@Sail.Stanford.edu, CommonLoops.pa@Xerox.COM
Fcc: BD:>Gregor>mail>outgoing-mail-2.text.newest
Message-ID: <19880711180221.8.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
Workshop for CLOS Users and Implementors
October 3rd and 4th
Xerox PARC
Palo Alto, California
We have been excited by the extent to which CLOS is already being
used, and the ways in which it is being extended. The purpose of
this workshop is to provide an opportunity for the members of the
CLOS community to get together and share their experience.
To provide a good start for the interchange, we are requesting that
participants supply a short position paper (1-3 pages) describing
work related to CLOS. Some topics of interest are:
Applications
Programming Techniques
Implementation
Programming Environment Tools
Extensions of CLOS
Techniques for Converting to CLOS
Meta Object Techniques and Theory
Critiques
We will try to support demonstrations or videotapes of applications,
programming environments, implementations or other relevant systems.
If you are planning to attend, please let us know by August 15th.
This will help us with planning and allow us to arrange a discount
rate at a local hotel.
Position papers should reach us by September 9th so that we can
organize a program and arrange for duplication of the papers.
Position papers, notice to attend, and other correspondence should
be sent to:
Gregor Kiczales
3333 Coyote Hill Rd.
Palo Alto, CA 94304
or by Internet mail to:
Gregor.pa@Xerox.com
-------
∂12-Jul-88 0942 Common-Lisp-mailer L&FP Registration -- FINAL CALL
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 12 Jul 88 09:42:21 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA10136; Tue, 12 Jul 88 10:42:01 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA26236; Tue, 12 Jul 88 10:41:49 MDT
Date: Tue, 12 Jul 88 10:41:49 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8807121641.AA26236@cons.utah.edu>
To: common-lisp@sail.stanford.edu, fp@cs.yale.edu, scheme@mc.lcs.mit.edu
Subject: L&FP Registration -- FINAL CALL
This is the final call for registration for the conference. ACM is
accepting registration by EMAIL, so please send your information to
them (meetings@acmvm.bitnet). Note, if you plan on using a credit
card, please include the name on the card, the type of card, the
number, and the expiration date. Also, please include the following
information. NOTE -- the final deadline for advance registration is
this FRIDAY, JULY 15. Also, you will have to make your own
reservations at Snowbird by calling Snowbird Central Reservations at
(800)453-3000 or (801)532-1700.
It looks like it will be a great conference. We are looking forward to
seeing you there.
Bob.
====================================================================
====================== L&FP 88 Registration Form ====================
The registration fees for applications prior to June 24 are:
Student $75
ACM or SIG (PLAN, ART, or ACT) Member Only $250
ACM and SIG Member $225
Non-Member $290
The registration fees for applications after that date are:
Student $100
ACM or SIG (PLAN, ART, or ACT) Member Only $300
ACM and SIG Member $275
Non-Member $350
Additional banquet tickets (for students or guests) are $40
Additional luncheon tickets are $12.50
Make your own application form including
Your Name
Company/Institution
Address
Telephone
E-mail Address
Membership status in ACM and SIGPLAN/SIGART/SIGACT including
membership number
Your fee category (as described above)
Your order for any extra banquet or luncheon tickets
Total fees enclosed
Form of payment (check/credit card)
Credit card type (Mastercard, Visa, or Amer Express), number,
expiration date, and signature if paying by credit card
Mailing List Restriction: (one of No Restictions, ACM and Other
Society Announcements, ACM Announcements)
If paying by check, make check payable (in US funds only!) to:
ACM LFP '88
Mail your form and payment to:
ACM LFP '88
P.O. Box 12105
Church Street Station
New York, NY 10249
∂15-Jul-88 1302 Common-Lisp-mailer overloading defstruct accessors
Received: from burdvax.PRC.Unisys.COM (PRC-GW.PRC.UNISYS.COM) by SAIL.Stanford.EDU with TCP; 15 Jul 88 13:02:28 PDT
Received: from caesar.PRC.Unisys.COM by burdvax.PRC.Unisys.COM (5.59/Domain/jpb/2.9)
id AA24404; Fri, 15 Jul 88 16:01:27 EDT
Received: from hamlet.PRC.Unisys.COM by caesar.PRC.Unisys.COM (3.2/Domain/jpb/2.9)
id AA10285; Fri, 15 Jul 88 16:01:11 EDT
Message-Id: <8807152001.AA10285@caesar.PRC.Unisys.COM>
Received: by hamlet.PRC.Unisys.COM (3.2/Domain/jpb/2.9)
id AA08031; Fri, 15 Jul 88 16:01:08 EDT
Date: Fri, 15 Jul 88 16:01:08 EDT
From: fritzson@PRC.Unisys.COM
To: Common-Lisp@Sail.Stanford.edu
Subject: overloading defstruct accessors
The following example can be viewed as an attempt to overload the
accessor function "get-a" by making it access the "get-a" fields of
both a "foo" structure and a "bar" structure.
-------
(defstruct (foo (:conc-name ())) get-a)
(defstruct (bar (:conc-name ()) (:include foo)) get-b)
(setq afoo (make-foo :get-a 1))
(setq abar (make-bar :get-a 2 :get-b 3))
-------
One could argue that the second defstruct redefines the accessor
function "get-a" so that it will only work on bar-s. On the other
hand, it is relatively easy to implement this so that "get-a" will
work both on foos and bars.
Xerox Common Lisp (Lyric release) objects to
(get-a afoo)
by complaining that "afoo is not a bar". Franz Allegro Common Lisp
allows it. I haven't tried any other lisps.
Is there a consensus on what an implementation of Common Lisp should
do with this?
-Rich Fritzson
ARPA: fritzson@prc.unisys.com
UUCP: {sdcrdcf,psuvax1,cbmvax}!burdvax!fritzson
P.S. Please, no complaints about the stylistic appropriateness of
using (:conc-name nil) in this way. This was written by someone who
should be using CLOS.
∂15-Jul-88 1341 Common-Lisp-mailer overloading defstruct accessors
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 15 Jul 88 13:41:26 PDT
Received: by labrea.stanford.edu; Fri, 15 Jul 88 13:40:27 PDT
Received: from rainbow-warrior.lucid.com by edsel id AA07098g; Fri, 15 Jul 88 13:37:11 PDT
Received: by rainbow-warrior id AA03925g; Fri, 15 Jul 88 13:37:32 PDT
Date: Fri, 15 Jul 88 13:37:32 PDT
From: Patrick Dussud <edsel!dussud@labrea.stanford.edu>
Message-Id: <8807152037.AA03925@rainbow-warrior.lucid.com>
To: fritzson@prc.unisys.com
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: fritzson@PRC.Unisys.COM's message of Fri, 15 Jul 88 16:01:08 EDT <8807152001.AA10285@caesar.PRC.Unisys.COM>
Subject: overloading defstruct accessors
Date: Fri, 15 Jul 88 16:01:08 EDT
From: fritzson@PRC.Unisys.COM
The following example can be viewed as an attempt to overload the
accessor function "get-a" by making it access the "get-a" fields of
both a "foo" structure and a "bar" structure.
-------
(defstruct (foo (:conc-name ())) get-a)
(defstruct (bar (:conc-name ()) (:include foo)) get-b)
(setq afoo (make-foo :get-a 1))
(setq abar (make-bar :get-a 2 :get-b 3))
-------
CLtL is pretty clear about this, the structure accessors defined for foo
should apply to instances of bar. The definition of bar should not obliterate
the definition of the accessor for the foo structure.
Patrick.
∂15-Jul-88 1342 Common-Lisp-mailer overloading defstruct accessors
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 15 Jul 88 13:41:56 PDT
Received: by labrea.stanford.edu; Fri, 15 Jul 88 13:40:52 PDT
Received: from blacksox.lucid.com by edsel id AA07108g; Fri, 15 Jul 88 13:37:57 PDT
Received: by blacksox id AA01410g; Fri, 15 Jul 88 13:34:01 pdt
Date: Fri, 15 Jul 88 13:34:01 pdt
From: Eric Benson <edsel!eb@labrea.stanford.edu>
Message-Id: <8807152034.AA01410@blacksox.lucid.com>
To: fritzson@prc.unisys.com
Cc: Common-Lisp@sail.stanford.edu
In-Reply-To: fritzson@PRC.Unisys.COM's message of Fri, 15 Jul 88 16:01:08 EDT <8807152001.AA10285@caesar.PRC.Unisys.COM>
Subject: overloading defstruct accessors
Date: Fri, 15 Jul 88 16:01:08 EDT
From: fritzson@PRC.Unisys.COM
The following example can be viewed as an attempt to overload the
accessor function "get-a" by making it access the "get-a" fields of
both a "foo" structure and a "bar" structure.
-------
(defstruct (foo (:conc-name ())) get-a)
(defstruct (bar (:conc-name ()) (:include foo)) get-b)
(setq afoo (make-foo :get-a 1))
(setq abar (make-bar :get-a 2 :get-b 3))
-------
One could argue that the second defstruct redefines the accessor
function "get-a" so that it will only work on bar-s. On the other
hand, it is relatively easy to implement this so that "get-a" will
work both on foos and bars.
Xerox Common Lisp (Lyric release) objects to
(get-a afoo)
by complaining that "afoo is not a bar". Franz Allegro Common Lisp
allows it. I haven't tried any other lisps.
Lucid Common Lisp originally (in Release 1.0) had the behavior you
describe in Xerox Common Lisp. This was changed in later releases so
that the GET-A defined by FOO is not replaced by the GET-A defined by
BAR. There is no structure slot access type checking in Franz Allegro
Common Lisp or MIT-derived Lisp Machines, other than making sure the
argument is an array whose length is greater than the index of the
slot being accessed.
Is there a consensus on what an implementation of Common Lisp should
do with this?
My personal opinion is that it is a bug for BAR to define GET-A such
that only objects of type BAR are allowed. It is easy to overlook
this problem, as I did until someone discovered it. It is too bad
(but probably not offically wrong) that many implementations of
DEFSTRUCT don't do any type checking. I think this is a legacy of
DEFSTRUCT's origin as "just a way to give mnemonic names to array
slots." For example, in Zetalisp the default was for DEFSTRUCTs to be
unnamed, rather like :TYPE VECTOR in CL.
-Rich Fritzson
ARPA: fritzson@prc.unisys.com
UUCP: {sdcrdcf,psuvax1,cbmvax}!burdvax!fritzson
P.S. Please, no complaints about the stylistic appropriateness of
using (:conc-name nil) in this way. This was written by someone who
should be using CLOS.
∂15-Jul-88 2001 Common-Lisp-mailer (Not Necessarily Common) LISP Implementation
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 15 Jul 88 20:01:41 PDT
Received: from [129.59.100.1] by uunet.UU.NET (5.59/1.14)
id AA09377; Fri, 15 Jul 88 23:00:37 EDT
Received: from backup.vuse.vanderbilt.edu by vuse.vanderbilt.edu (3.2/SMI-3.2)
id AA00651; Fri, 15 Jul 88 21:59:33 CDT
Received: by backup.vuse.vanderbilt.edu (4.0/SMI-4.0)
id AA00247; Fri, 15 Jul 88 21:59:50 CDT
Date: Fri, 15 Jul 88 21:59:50 CDT
From: drl@vuse.vanderbilt.edu (David R. Linn)
Message-Id: <8807160259.AA00247@backup.vuse.vanderbilt.edu>
To: Common-Lisp@SAIL.Stanford.EDU
Subject: (Not Necessarily Common) LISP Implementation
(Hopefully)Gentle Readers,
I recently requested information from the readers of the
AIList mailing list about implementations of LISP that do not
rely (in some way) on a LISP interpreter and now wish to request
the same of those readers of the Common LISP mailing list as well.
I realize that this question is not really about Common LISP but
I also realize the depth and breadth of the LISP experience of the
readers of this list.
From the initial repsonses to my question, I understand
that I probably did not phrase my question in the best possible way.
When I refer to a LISP interpreter, I refer not to the evaluator alone
but to the program that includes the evaluator, memory manager, reader,
printer and other such; perhaps I should call this a LISP "environmental
support program". ("Virtual machine" came to mind but was discarded as
another multiply-interpretable phrase.)
To attempt to find a Common LISP connection in all of this,
let me recast my question my question in terms of compiling LISP
(which I understand was a central concern of the Common LISP movement):
Does anyone have any experience with an implementation of LISP which
uses a C/Fortran compiler/link-with-external-runtime-library scheme
instead of interpret-or-compile-and-run-within-the-environmental-support-
program?
Please reply directly to me and I will summarize anything of interest
to the list
David
David Linn, System Manager/Postmaster |INET:
Vanderbilt University School of Engineering| drl@vuse.vanderbilt.edu
Post Office Box 1824, Station B |Phone:
Nashville, TN, USA 37235 | [USA] 615-322-7924
∂16-Jul-88 1818 Common-Lisp-mailer Franz Inc. makes available Allegro CL/GNU Emacs Interface
Received: from ucbarpa.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 16 Jul 88 18:18:52 PDT
Received: by ucbarpa.Berkeley.EDU (5.59/1.28)
id AA18764; Sat, 16 Jul 88 18:18:00 PDT
Received: from akbar by franz (3.2/3.14)
id AA04867; Sat, 16 Jul 88 18:07:42 PDT
Received: by akbar (3.2/3.14)
id AA11821; Sat, 16 Jul 88 18:07:46 PDT
From: franz!akbar!layer@ucbarpa.Berkeley.EDU (Kevin Layer)
Return-Path: <akbar!layer>
Message-Id: <8807170107.AA11821@akbar>
To: franz!su-ai.stanford.edu!common-lisp
Subject: Franz Inc. makes available Allegro CL/GNU Emacs Interface
Date: Sat, 16 Jul 88 18:07:45 PDT
Introduction
------------
Franz Inc. is offering to the Lisp community version 1.2 of their
interface between Allegro Common Lisp (previously known as "Extended
Common Lisp") and GNU Emacs. This interface will also work between
GNU Emacs and Franz Lisp Opus 43 (the current release from Franz Inc.)
or Franz Lisp Opus 38 (the last public domain version).
The goal of this interface is to offer the Lisp programmer a tightly
integrated Lisp environment. The interface can be broken down into
three parts:
* Lisp editing modes for Common and Franz Lisp,
* Inferior modes for Common and Franz Lisp subprocesses, and
* TCP Common Lisp modes for socket communication with Common
Lisp.
The first two are available for both Common and Franz Lisp, but the
third feature, which enables the tight coupling of the environments,
is only available for Allegro CL. It uses multiprocessing in Allegro
CL and UNIX domain socket to communicate information between the GNU
Emacs and Allegro CL worlds.
The features of the interface are:
* enhanced subprocess modes, including
- file name completion
- an input ring to allow fetching of previously typed input
* macroexpansion of forms in a Lisp source file
* `find-tag' for Lisp functions (the Allegro CL world is
queried for the location of Lisp functions)
* who-calls: find all callers of a Lisp function
* Arglist, `describe' and function documentation are available
in Lisp source buffers (again, the information comes
dynamically from Allegro CL)
* automatic indentation of forms entered to an inferior Lisp
The interface is written entirely in GNU Emacs Lisp, with the
exception of a replacement for the standard `open-network-stream' in
src/process.c. Some of the advanced features use UNIX domain sockets
and also use features specific to the implementation of Allegro CL
(multiprocessing).
The interface is fully documented on-line.
Ownership
---------
The Lisp/GNU Emacs interface is the property of Franz Incorporated.
The Emacs Lisp source code is distributed and the following notice is
present in all source files for which it applies:
;;
;; copyright (C) 1987, 1988 Franz Inc, Berkeley, Ca.
;;
;; The software, data and information contained herein are the property
;; of Franz, Inc.
;;
;; This file (or any derivation of it) may be distributed without
;; further permission from Franz Inc. as long as:
;;
;; * it is not part of a product for sale,
;; * no charge is made for the distribution, other than a tape
;; fee, and
;; * all copyright notices and this notice are preserved.
;;
;; If you have any comments or questions on this interface, please feel
;; free to contact Franz Inc. at
;; Franz Inc.
;; Attn: Kevin Layer
;; 1995 University Ave
;; Suite 275
;; Berkeley, CA 94704
;; (415) 548-3600
;; or
;; emacs-info%franz.uucp@Berkeley.EDU
;; ucbvax!franz!emacs-info
Some files contain GNU Emacs derived code, and those files contain
the GNU Emacs standard copyright notice.
Obtaining the Software
----------------------
To obtain version 1.2 of this interface either:
1) copy it from ucbarpa.berkeley.edu or ucbvax.berkeley.edu via FTP
(login `ftp', password your login name) from the directory
pub/fi/gnudist-1.2-tar.Z, or
2) send a check (sorry, no PO's accepted) in the amount of $50 for a
US address and $75 for a foreign address to Franz Inc. to the
following address:
Franz Inc.
Attn: Emacs/LISP Interface Request
1995 University Ave
Suite 275
Berkeley, CA 94704
Please specify the media (`tar' format only) which is one of:
* 1/2", 1600 bpi, 9-track
* 1/4", cartridge tape--specify the machine type (ie, TEK, SUN)
Future Work
-----------
Improvements to this interface will be made in the future, so to
facilitate the exchange of information about this and user's
experiences, questions and suggestions a mailing list will be created
as a forum for discussion on topics relating to this interface. If
you would like to be on this mailing list (local redistribution is
encouraged), please drop me a note. If you have trouble with one of
the addresses below, try one of:
layer@Berkeley.EDU
-or-
ucbvax!layer
----------------------------------------------------------------------------
D. Kevin Layer Franz Inc.
layer%franz.uucp@Berkeley.EDU 1995 University Avenue, Suite 275
ucbvax!franz!layer Berkeley, CA 94704
(415) 548-3600, FAX: (415) 548-8253
∂18-Jul-88 1555 Common-Lisp-mailer (Not Necessarily Common) LISP Implementation
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 18 Jul 88 15:53:43 PDT
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06197; 18 Jul 88 21:00 BST
Received: from xenakis by mordell.maths.bath.AC.UK id aa27384;
18 Jul 88 21:24 BST
To: drl%vuse.vanderbilt.edu@NSS.Cs.Ucl.AC.UK
CC: Common-Lisp@sail.stanford.edu
In-reply-to: "David R. Linn"'s message of Fri, 15 Jul 88 21:59:50 CDT <8807160259.AA00247@backup.vuse.vanderbilt.edu>
Subject: (Not Necessarily Common) LISP Implementation
Date: Mon, 18 Jul 88 21:24:34 BST
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
I tried to reply to your original message with commnets on POPLOG and
the BALM system at Utah, but these where systems without an
interpreter. In my opinion a system such as you describe would not be
LISP as it loses all the advantages of program development.
Having said that I have an experimental system which compiles LISP
into C, and that is linked with a fixed library. The target is a
fixed languages rather than a LISP system. Is that what you mean?
Another possible interpretation: we wrote a LISp system which was
constructed by compiling LISP into ALGOL-60, the final thing looking
like LISP, but with no compiler.
==John
∂18-Jul-88 2049 Common-Lisp-mailer arithmeticprecision
Received: from ICS.UCI.EDU by SAIL.Stanford.EDU with TCP; 18 Jul 88 20:49:23 PDT
Received: from cip.ics.uci.edu by ICS.UCI.EDU id aa05147; 18 Jul 88 20:46 PDT
Received: from cip2.ics.uci.edu by CIP.ICS.UCI.EDU id aa01852;
18 Jul 88 20:44 PDT
To: Common-Lisp%sail.stanford.edu@ICS.UCI.EDU
Subject: arithmeticprecision
Reply-to: Bernd Nordhausen <bernd%cip.ics.uci.edu@ICS.UCI.EDU>
Date: Mon, 18 Jul 88 20:44:36 -0700
From: Bernd Nordhausen <bernd%cip.ics.uci.edu@ICS.UCI.EDU>
Message-ID: <8807182044.aa01852@CIP.ICS.UCI.EDU>
Is there an easy way in Common Lisp (especially in KCL) to specify the
precision of arithmetic functions (=, +, -, etc.) ? In other words how
can I make
(= 300.0000001 300.00) return T
without having to write a new = funnction?
Bernd
∂19-Jul-88 0102 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 19 Jul 88 01:01:54 PDT
Received: by labrea.stanford.edu; Tue, 19 Jul 88 01:00:50 PDT
Received: from bhopal.lucid.com by edsel id AA20315g; Mon, 18 Jul 88 23:37:58 PDT
Received: by bhopal id AA05670g; Mon, 18 Jul 88 23:38:35 PDT
Date: Mon, 18 Jul 88 23:38:35 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8807190638.AA05670@bhopal.lucid.com>
To: jrose@sun.com
Cc: goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: John Rose's message of Thu, 30 Jun 88 12:40:54 PDT <8806301940.AA01804@lukasiewicz.sun.com>
Subject: EQUAL, and hash tables, and value/object distinctions
[have been out of town for some time, and under other time constraints,
so apologies in advance for replying to "old mail"]
re: First, if EQUAL is going to descend structures and arrays to test
for isomorphism, it should compare hash tables for equality
according to their contents. That is, it should verify
that two possibly-equal hash tables have the same set of
keys, and that for each key the two stored values are EQUAL.
Key equality testing must be done using each table's
key comparison function.
That's a lot of very strong words for what must be considered an
opinion on how EQUAL could be extended to the case of hash-tables.
The difficulty is that EQUAL has, until now, been a very low-level
simple-minded component-wise equivalence test. What you are proposing
is something that looks much more grandiose than even EQUALP. While
I might see some partial utility in these relations that equated
more things (e.g., 3/2 and 1.5 are EQUALP), and those that refined
EQUAL (e.g., "graph-isomorphism" equates fewer things than EQUAL), I
don't see why EQUAL should bear the burden of being anything more than
a "simple-minded component-wise equivalence test."
re: Date: Wed, 29 Jun 88 18:57:09 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
. . . At one time, there was a suggestion that hash tables admit
a user-supplied equivalence predicate; but it never got very far for
just this reason, that the equivalence predicate must be *** paired up**
with an appropriate "numericalizer" function, and many implementors felt
that users wouldn't understand these issues and wouldn't be able to
construct up their own versions of sxhash to go with their alleged
equivalence predicates.
Yuck. Who are these brilliant Implementors, that we may all worship
at their feet? For they are the curators of such profound knowledge as
(EQUALITY-PREDICATE X Y) ==> (= (HASH-FN X) (HASH-FN Y))
If we mere Users cannot be trusted with such wisdom, how are we to
navigate the Streams of Extensibility, or handle the Objects of
Genericity? Oh great Implementors, save us, we pray, from overmuch
functionality.
Seriously, I hear an alarming amount of condescension in the above
reasoning.
The above logical implication is ALL THAT IS NEEDED to construct an
appropriate hash function. It is the sole and fundamental insight which
makes hash tables work; I have relied on it for years, building many a
hash table in various extensible frameworks. What's the problem of
requiring a hash-table builder from promising that his hash and equality
functions bear the simple relation to each other? And if he can't
There is no :HASH-FN argument to make-hash-table in CL; and I presume you
mean the :TEST argument when you say :EQUALITY-PREDICATE? The last time
on this mailing list that I suggested having user-suppled equivalence
predicates for hash-tables, there was:
(1) a lot of argumentation over what to call the replacement for SXHASH
[a ":test" argument isn't enough, if you give an equivalence relation
for which the system-supplied SXHASH function isn't "good enough" in
the sense I spoke about before]
(2) comments from Symbolics folks that they had discussed these ideas
internally, and rejected them because of the potential for confusion
over the SXHASH correlation issue.
You might try asking Dave Moon what the issues were, if you are really
interested. It may be that the close link between methods on EQUAL and
methods on SXHASH is one reason that CLOS doesn't say much about EQUAL.
-- JonL --
∂19-Jul-88 0102 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 19 Jul 88 01:02:39 PDT
Received: by labrea.stanford.edu; Tue, 19 Jul 88 01:01:35 PDT
Received: from bhopal.lucid.com by edsel id AA20478g; Tue, 19 Jul 88 00:04:54 PDT
Received: by bhopal id AA05728g; Tue, 19 Jul 88 00:05:31 PDT
Date: Tue, 19 Jul 88 00:05:31 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8807190705.AA05728@bhopal.lucid.com>
To: Greenwald@stony-brook.scrc.symbolics.com
Cc: jrose@sun.com, goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Thu, 30 Jun 88 16:36 EDT <19880630203650.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
re: For example, one cannot construct a hash-function for #'= unless you limit
the valid keys to not include both a floating point number and two
integers that both coerce to that same float.
You must be referring to the bug in CLtL, p194:
"When rational and floating-point numbers are compared or
combined by a numerical function, the rule of floating-point
contagion is followed: ..."
I believe that this should read:
"When rational and floating-point numbers are
combined by a numerical function, the rule of floating-point
contagion is followed: ..."
Float conversion is an inherently information-losing process; this is,
of course, fine for situations where there will most likely be information
loss anyway ,due to rounding and/or truncation [such as in "combination by
a numerical function"]. But numerical equality and inequalities are not
information losing, and should in fact be transitive relations. About
one year ago, I pointed out this difficulty to Guy Steele with some well-
chosen examples; and he was quite shocked -- indeed it was his intention
that "=" be a true equivalence predicate.
Lucid's 3.0 release performs "appropriate contagion" in the case of
numerical comparisons, in order to preserve transitivity.
re: Hash tables aren't so complicated that one can't construct them
yourself. My guess (and only a guess) is that the only reason they're
included in the language spec is to give a portable way of hashing on
%pointer where that might be useful. SXHASH would have been enough, and
that allows easy implementation of the common case of EQUAL hash tables,
too.
Efficient hash tables are! ["so complicated that one can't construct them ...].
Both Lucid and Symbolics hide a lot of implementation-dependent knowledge
deep within the bowels of CL hash-tables; even if the average Lisp programmer
were "smart enough" to defend his ego on hash-tables, he probably wouldn't
have reasonable access to all the system internals that the vendor wizards do.
In fact, I have heard some C programmers praise Common Lisp for it's inclusion
of hash-tables. They complain and complain about having to reinvent the
wheel (hash-tables) over and over again.
re: Date: Thu, 30 Jun 88 12:40:54 PDT
From: jrose@Sun.COM (John Rose)
. . .
Yuck. Who are these brilliant Implementors, that we may all worship
at their feet? For they are the curators of such profound knowledge as
(EQUALITY-PREDICATE X Y) ==> (= (HASH-FN X) (HASH-FN Y))
Yes, but the equality-predicate must be transitive over the domain of
possible keys in order for a hash-function to work.
This point that you [Greenwald] are making seems not to be generally
appreciated. The fact that many many experts pored over the Common
Lisp design, and still thought that numerical equality as defined by
"=" was an equivalence relation shows how easy it is to miss closure
on transitivity.
-- JonL --
∂19-Jul-88 0826 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 19 Jul 88 08:25:59 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 435124; Tue 19-Jul-88 11:23:22 EDT
Date: Tue, 19 Jul 88 11:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
To: Jon L White <edsel!jonl@labrea.stanford.edu>
cc: Greenwald@STONY-BROOK.SCRC.Symbolics.COM, jrose@sun.com, goldman@vaxa.isi.edu,
common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <8807190705.AA05728@bhopal.lucid.com>
Message-ID: <19880719152249.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Tue, 19 Jul 88 00:05:31 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
....numerical equality and inequalities are not
information losing, and should in fact be transitive relations. About
one year ago, I pointed out this difficulty to Guy Steele with some well-
chosen examples; and he was quite shocked -- indeed it was his intention
that "=" be a true equivalence predicate.
I agree that = should be transitive even when floating-point numbers are
involved. I.e. (= (/ 10.0 single-float-epsilon)
(1+ (floor (/ 10.0 single-float-epsilon))))
should be NIL, since
(= (/ 10.0 single-float-epsilon)
(floor (/ 10.0 single-float-epsilon)))
is certainly T and
(= (floor (/ 10.0 single-float-epsilon))
(1+ (floor (/ 10.0 single-float-epsilon))))
is certainly NIL. To understand this example better, it helps
to realize that (= (/ 10.0 single-float-epsilon)
(+ (/ 10.0 single-float-epsilon) 1.0))
is true in all implementations.
Since CLtL p.194 expressly forbids this, requiring the first form above
to return T, shouldn't somebody submit an X3J13 Cleanup subcommittee
proposal before it's too late?
Lucid's 3.0 release performs "appropriate contagion" in the case of
numerical comparisons, in order to preserve transitivity.
I'm a little surprised that Lucid would change their implementation
incompatibly with both CLtL and previous Lucid implementations without
first getting some concensus that the current definition of Common Lisp
is wrong and in fact will change. I know Symbolics specifically decided
not to "fix this bug" unilaterally when we noticed it some time ago,
considering that compatibility was more important. Chacun a son gout.
∂19-Jul-88 1256 Common-Lisp-mailer Question about readtable null arguments
Received: from cayuga.cs.rochester.edu (CS.ROCHESTER.EDU) by SAIL.Stanford.EDU with TCP; 19 Jul 88 12:56:32 PDT
Received: by cayuga.cs.rochester.edu (5.52/j) id AA07817; Tue, 19 Jul 88 15:55:40 EDT
Received: from loopback by lesath.cs.rochester.edu (3.2/j) id AA03377; Tue, 19 Jul 88 15:55:30 EDT
Message-Id: <8807191955.AA03377@lesath.cs.rochester.edu>
To: common-lisp@sail.stanford.edu
Subject: Question about readtable null arguments
Date: Tue, 19 Jul 88 15:55:20 -0400
From: quiroz@cs.rochester.edu
I just noticed a certain ambiguity (What else is new? :-) in CLtL that
I would like to get clarified.
In 22.1.5, p 361, the definitions of `copy-readtable' and of
`set-syntax-from-char' establish a convention that a NIL readtable
argument that is used as source for a copy, refers to the "standard
Common Lisp readtable". (This is slightly irregular, as in other
contexts an omitted argument is the same as a null argument, but I
digress.)
No such guarantee is given for other readtable arguments that happen
to be simultaneously optional and from-. There are (at least) two
other functions where this convention would be useful:
get-[dispatch-]macro-character both take an optional readtable from
which they copy some information. Both default to *readtable*. But
nothing is said about explicitly giving them NIL.
In spite of not giving an explicit guarantee (OR DID I MISS IT?),
Steele seems to believe that the same convention applies. In p 378,
he uses (get-macro-character #\) nil) with the comment "...Giving }
the same definition as the standard definition of the character )
has...", which makes me think he expects the "NIL means standard"
convention to apply.
I checked three implementations. Two of them (Symbolics and Xerox)
seem to take the benign interpretation, making Steele's example of p
378 work. KCl, on the other hand, sent me to the debugger:
>(get-macro-character #\) nil)
Error: NIL is not of type READTABLE.
Error signalled by GET-MACRO-CHARACTER.
Broken at GET-MACRO-CHARACTER. Type :H for Help.
>>
So, I'd appreciate hearing from the Lisp community, especially from
implementors:
1- Is there in CLtL an explicit statement of the convention that
optional readtable arguments, in from- usage, supplied with an
explicit NIL, should mean the standard readtable?
2- If not, is it nonetheless common to take that interpretation?
In your version of Common Lisp, (get-macro-character #\) nil)
2.a. Produces the macro function (perhaps nil) associated
with ) in the standard readtable.
2.b. Errors out.
2.c. Does something else (like checking the current readtable).
3- If your implementation takes the benign approach, what standard
functions have been implemented to show this behavior? (I guess
the get-... ones are the only ones, I'd like to know if I missed
another.)
I will summarize the responses. Thanks,
Cesar Quiroz
PS. I have patches (trivial) to make KCl behave nicely to the
example in p. 378. If you are interested, I can send them to you, or
post them if there is any interest.
∂19-Jul-88 1331 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 19 Jul 88 13:31:11 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA18904; Tue, 19 Jul 88 13:28:45 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0)
id AA29153; Tue, 19 Jul 88 13:29:10 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA23049; Tue, 19 Jul 88 13:30:51 PDT
Date: Tue, 19 Jul 88 13:30:51 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8807192030.AA23049@lukasiewicz.sun.com>
To: edsel!jonl@labrea.stanford.edu
Cc: goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Mon, 18 Jul 88 23:38:35 PDT <8807190638.AA05670@bhopal.lucid.com>
Subject: EQUAL, and hash tables, and value/object distinctions
Date: Mon, 18 Jul 88 23:38:35 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
[have been out of town for some time, and under other time constraints,
so apologies in advance for replying to "old mail"]
re: First, if EQUAL is going to descend structures and arrays to test
for isomorphism, it should compare hash tables for equality
according to their contents. That is, it should verify
that two possibly-equal hash tables have the same set of
keys, and that for each key the two stored values are EQUAL.
Key equality testing must be done using each table's
key comparison function.
That's a lot of very strong words for what must be considered an
opinion on how EQUAL could be extended to the case of hash-tables.
The difficulty is that EQUAL has, until now, been a very low-level
simple-minded component-wise equivalence test. What you are proposing
is something that looks much more grandiose than even EQUALP.
I think you missed my point. Let me try saying it with fewer
strong words. EQUAL currently recurs on the components of
CONS cells, and a few other types. There are proposals in
the air to add to the set of types whose components EQUAL
compares recursively. These types include arrays and structures.
I personally find these proposals rather aggressive or "grandiose",
as perhaps you do too. However, __if__ it makes overall sense
to treat the components of arrays and structures this way,
I believe it also makes sense to treat hash table components
in the same way, using a suitable definition of "component".
My contribution, I hope, is to point out that hash tables
do in fact have components quite analogous to array
or structure components, that these components are
the hash table's values, accessed using its keys,
and finally that this implies certain things about
the way hash table isomorphism is computed.
-- John
∂19-Jul-88 1438 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 19 Jul 88 14:37:48 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 435438; Tue 19-Jul-88 17:33:55 EDT
Date: Tue, 19 Jul 88 17:33 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: EQUAL, and hash tables, and value/object distinctions
To: Moon@STONY-BROOK.SCRC.Symbolics.COM, edsel!jonl@labrea.stanford.edu
cc: Greenwald@STONY-BROOK.SCRC.Symbolics.COM, jrose@sun.com, goldman@vaxa.isi.edu,
common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880719152249.9.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-ID: <19880719213338.0.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Tue, 19 Jul 88 11:22 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Date: Tue, 19 Jul 88 00:05:31 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
....numerical equality and inequalities are not
information losing, and should in fact be transitive relations. About
one year ago, I pointed out this difficulty to Guy Steele with some well-
chosen examples; and he was quite shocked -- indeed it was his intention
that "=" be a true equivalence predicate.
I agree that = should be transitive even when floating-point numbers are
involved. I.e. (= (/ 10.0 single-float-epsilon)
(1+ (floor (/ 10.0 single-float-epsilon))))
should be NIL, since
(= (/ 10.0 single-float-epsilon)
(floor (/ 10.0 single-float-epsilon)))
is certainly T and
(= (floor (/ 10.0 single-float-epsilon))
(1+ (floor (/ 10.0 single-float-epsilon))))
is certainly NIL. To understand this example better, it helps
to realize that (= (/ 10.0 single-float-epsilon)
(+ (/ 10.0 single-float-epsilon) 1.0))
is true in all implementations.
Without using the epsilon case:
(= 1234d20 (FLOOR 1234d20)) => T
(= 1234d20 (1+ (FLOOR 1234d20))) => T
but obviously (= (FLOOR 1234d20) (1+ (FLOOR 1234d20))) => NIL
Or, one of my favorite screw cases along these lines:
(LET ((A 1234d10))
(<= A (1+ (FLOOR A)) (COERCE A 'SINGLE-FLOAT) (FLOOR A)))
Since CLtL p.194 expressly forbids this, requiring the first form above
to return T, shouldn't somebody submit an X3J13 Cleanup subcommittee
proposal before it's too late?
I'll point out that in March 1987 JonL proposed the same thing, and Moon
suggested that the proposal be written up and submitted to the X3J13
committee. From this exchange can I conclude that nothing *was*
submitted? I'd guess that this suggestion is probably futile unless
someone actively volunteers to write up, and submit, the new floating
point contagion rule for comparisons.
Lucid's 3.0 release performs "appropriate contagion" in the case of
numerical comparisons, in order to preserve transitivity.
I'm a little surprised that Lucid would change their implementation
incompatibly with both CLtL and previous Lucid implementations without
first getting some concensus that the current definition of Common Lisp
is wrong and in fact will change. I know Symbolics specifically decided
not to "fix this bug" unilaterally when we noticed it some time ago,
considering that compatibility was more important. Chacun a son gout.
∂20-Jul-88 0107 Common-Lisp-mailer EQUAL, and hash tables, and value/object distinctions
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 20 Jul 88 01:07:45 PDT
Received: by labrea.stanford.edu; Wed, 20 Jul 88 01:06:40 PDT
Received: from bhopal.lucid.com by edsel id AA04469g; Wed, 20 Jul 88 00:54:51 PDT
Received: by bhopal id AA02880g; Wed, 20 Jul 88 00:55:34 PDT
Date: Wed, 20 Jul 88 00:55:34 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8807200755.AA02880@bhopal.lucid.com>
To: jrose@sun.com
Cc: goldman@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: John Rose's message of Tue, 19 Jul 88 13:30:51 PDT <8807192030.AA23049@lukasiewicz.sun.com>
Subject: EQUAL, and hash tables, and value/object distinctions
re: My contribution, I hope, is to point out that hash tables
do in fact have components quite analogous to array
or structure components, that these components are
the hash table's values, accessed using its keys,
and finally that this implies certain things about
the way hash table isomorphism is computed.
Ah, I see your point now. Put this way, it looks much different. Thanks.
-- JonL --
∂20-Jul-88 0143 Common-Lisp-mailer Contagion on numerical comparisons
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 20 Jul 88 01:43:28 PDT
Received: by labrea.stanford.edu; Wed, 20 Jul 88 01:42:20 PDT
Received: from bhopal.lucid.com by edsel id AA04700g; Wed, 20 Jul 88 01:35:52 PDT
Received: by bhopal id AA02976g; Wed, 20 Jul 88 01:36:34 PDT
Date: Wed, 20 Jul 88 01:36:34 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8807200836.AA02976@bhopal.lucid.com>
To: Greenwald@stony-brook.scrc.symbolics.com,
Moon@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Tue, 19 Jul 88 17:33 EDT <19880719213338.0.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: Contagion on numerical comparisons
re: [Jonl: the CL numeric comparisons should be transitive functions.]
[Moon: this violates CLtL; shouldn't we have a cleanup issue for it?]
I'll point out that in March 1987 JonL proposed the same thing, and Moon
suggested that the proposal be written up and submitted to the X3J13
committee. From this exchange can I conclude that nothing *was*
submitted? I'd guess that this suggestion is probably futile unless
someone actively volunteers to write up, and submit, the new floating
point contagion rule for comparisons.
This "proposal" has been on my list of items "to be submitted". A hardcopy
of this list was passed-out to cl-cleanup committee members who were actually
present at the March 1988 meeting in Palo Alto, and commentary was invited.
The relevant paragraph was:
``Specify that the numerical comparison functions (CLtL, p196) are
transitive operations; thus the phrase "required coercions" can't
be interpreted to mean "float contagion" (probably "rational contagion"
is needed for comparisons, whereas "float contagion" is needed for the
other operations). Although this contradicts the statement on p194,
third paragraph, but the mathematics is much better.''
Only a handful of persons actually gave me feedback on priorities for this
list, and the numeric-comparison transitivity issue didn't rate very high
in anyone's book.
Note that your(plural) examples were all malice-aforethought cases on
numerical-equality; but numeric inequalities are involved also, and are
probably even more important [because doing an EQL comparison between a
float and a rational that can't be exactly represented by a float is
probably a conceptual bug; but doing a < or <= comparison is still
meaningful, modulo "fence-posts"]. For a world with 24-bit mantissas
(e.g., ieee "single-floats") float-contagion on comparisons will lead to
the following absurdity:
(setq i #x2000000) ==> 33554432
(setq fx (float i)) ==> 3.3554432E7
Now
(<= fx (+ i 1)) ==> T
(< (+ i 1) (+ i 2)) ==> T
(<= (+ i 2) fx) ==> T
which is summarized by:
fx <= i+1 < i+2 <= fx
Or, put bluntly, fx < fx, an absurdity.
Maybe it will be impossible to get complete consensus on this issue, as
some dyed-in-the-wool FORTRANer's may insist that compatibililty with the
1950's behaviour is preferable to transitivity. But at Lucid, some time ago,
we finally decided to bite the bullet, knowing that the fix will hardly break
any reasonable programs, and not fixing it will break some obscure programs.
I plan to submit a select subset of my "to be submitted" list as proposals
to the x3j13 cleanup committe sometime well before mid-September.
-- JonL --
∂20-Jul-88 0853 Common-Lisp-mailer L&FP Transportation
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 20 Jul 88 08:52:57 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA17258; Wed, 20 Jul 88 09:50:39 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA03528; Wed, 20 Jul 88 09:50:19 MDT
Date: Wed, 20 Jul 88 09:50:19 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8807201550.AA03528@cons.utah.edu>
To: common-lisp@sail.stanford.edu, scheme@mc.lcs.mit.edu, fp@cs.yale.edu
Cc: chaillou@inria.inria.fr, cork@rice.edu, kessler%cons@cs.utah.edu
Subject: L&FP Transportation
For those of you arriving at the Salt Lake International Airport and
wanting transportation to Snowbird, here is the information.
Canyon Transportation has van service between the airport and
Snowbird. The charge is $10 per person, unless you are the only
person in the van, in which case the charge will be $20. They are
planning to be at the airport between 10 am and 10 pm on Saturday the
23rd and the same hours on Sunday the 24th. Look for ground
transportation after you claim your baggage and you should find them.
They may be stationed inside the airport near the baggage claim, or
outside at the curb.
If you need to make special arrangements with them, particularily,
outside of the 10am to 10pm hours, you may call them at the following
number:
(800)255-1841
You can also take a taxi, but that will cost around $40.
Bob.
∂20-Jul-88 1048 Common-Lisp-mailer hash tables
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 20 Jul 88 10:48:11 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06458; 20 Jul 88 18:41 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Wed, 20 Jul 88 18:36:30 BST
Message-Id: <8470.8807201736@subnode.aiai.ed.ac.uk>
To: Greenwald@scrc-stony-brook.arpa,
jonl <@labrea.stanford.edu:jonl@edsel.uucp>
Subject: hash tables
Cc: common-lisp@sail.stanford.edu, goldman@vaxa.isi.edu, jrose@sun.com
> Date: Tue, 19 Jul 88 00:05:31 PDT
> From: Jon L White <jonl%edsel@edu.stanford.labrea>
> In fact, I have heard some C programmers praise Common Lisp for it's inclusion
> of hash-tables. They complain and complain about having to reinvent the
> wheel (hash-tables) over and over again.
Apropos of hash tables, one feature of Pop(Log) that I sometimes want
to have is "temporary properties". They are essentially hash tables
such that being in them does not prevent being garbage collected. An
object might have a property (in this table) and nonetheless be
collectable. Is there some problem with such tables that makes them
not a good idea? They certainly seem to be something users can't
write for themselves.
-- Jeff
∂21-Jul-88 0933 Common-Lisp-mailer hash tables and GC
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 21 Jul 88 09:33:45 PDT
Posted-Date: Thu, 21 Jul 88 09:33:27 PDT
Message-Id: <8807211633.AA27307@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA27307; Thu, 21 Jul 88 09:33:30 PDT
To: jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
From: goldman@vaxa.isi.edu
Subject: hash tables and GC
Cc: common-lisp@sail.stanford.edu
Date: Thu, 21 Jul 88 09:33:27 PDT
Sender: goldman@vaxa.isi.edu
Apropos of hash tables, one feature of Pop(Log) that I sometimes want
to have is "temporary properties". They are essentially hash tables
such that being in them does not prevent being garbage collected. An
object might have a property (in this table) and nonetheless be
collectable. Is there some problem with such tables that makes them
not a good idea? They certainly seem to be something users can't
write for themselves.
I'm not sure just what you mean by "being in" a hash table. I have
commonly seen the following case -- is it what you have in mind?
I have an EQ hash table H. My program will never apply the MAPHASH accessor
to H. Therefore, the fact that H is accessible to my program does NOT
imply that any of the keys or values are accessible. If the pair [K V]
is in the table, then if K is independently accessible, V is also
accessible. But if K is not independently accessible, it is garbage, and
so is V unless V is independently accessible.
Do any implementations have "non-mappable" hash tables and a Garbage
Collector that takes this into account? [The condition that the hash
table equivalence be EQ was only stated to make the explanation simple to
follow intuitively. If we think of the key K as an exemplar of
some equivalence class, and regard the phrase "K is independently
accessible" as meaning "some element of the equivalence class
containing K is independently accessible", then the rationale holds
regardless of the table's equivalence predicate, and can, in fact, be
conservatively followed for EQL and EQUAL hash tables.
Neil
∂21-Jul-88 1138 Common-Lisp-mailer Re: hash tables and GC
Received: from rdcf.sm.unisys.com (SM.UNISYS.COM) by SAIL.Stanford.EDU with TCP; 21 Jul 88 11:37:57 PDT
Received: by rdcf.sm.unisys.com (sdcrdcf) (5.51/Domain/jpb/2.9.1.4)
id AA02583; Thu, 21 Jul 88 11:42:27 PDT
Message-Id: <8807211842.AA02583@rdcf.sm.unisys.com>
Received: from XAVIER by sdcrdcf with PUP; Thu, 21 Jul 88 11:42 PDT
From: darrelj@sm.unisys.com
Date: 21 Jul 88 11:36 PDT (Thursday)
Subject: Re: hash tables and GC
In-Reply-To: goldman@vaxa.isi.edu's message of Thu, 21 Jul 88 09:33:27 PDT
To: goldman@vaxa.isi.edu
Cc: jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk, common-lisp@sail.stanford.edu
To: jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
From: goldman@vaxa.isi.edu
Subject: hash tables and GC
Cc: common-lisp@sail.stanford.edu
Date: Thu, 21 Jul 88 09:33:27 PDT
Sender: goldman@vaxa.isi.edu
Do any implementations have "non-mappable" hash tables and a Garbage
Collector that takes this into account?
Neil
Interlisp-10 does this for all hash tables, although certain cases of
keys involving "permanent" objects like SMALLP numbers are never
automatically removed. It also looks like pretty complicated code to
implement it. At first blush, it seems like it would be much harder
to do in some incremental GC scheme as it requires scanning all such
hash tables before recycling objects they contain.
∂22-Jul-88 0447 Common-Lisp-mailer hash tables and GC
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 22 Jul 88 04:47:21 PDT
Received: by labrea.stanford.edu; Fri, 22 Jul 88 04:46:05 PDT
Received: from bhopal.lucid.com by edsel id AA06715g; Fri, 22 Jul 88 04:41:55 PDT
Received: by bhopal id AA04252g; Fri, 22 Jul 88 04:42:47 PDT
Date: Fri, 22 Jul 88 04:42:47 PDT
From: Jon L White <edsel!jonl@labrea.stanford.edu>
Message-Id: <8807221142.AA04252@bhopal.lucid.com>
To: darrelj@sm.unisys.com
Cc: goldman@vaxa.isi.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk,
common-lisp@sail.stanford.edu
In-Reply-To: darrelj@sm.unisys.com's message of 21 Jul 88 11:36 PDT (Thursday) <8807211842.AA02583@rdcf.sm.unisys.com>
Subject: hash tables and GC
re: Interlisp-10 does this for all hash tables, although certain cases of
keys involving "permanent" objects like SMALLP numbers are never
automatically removed. It also looks like pretty complicated code to
implement it. At first blush, it seems like it would be much harder
to do in some incremental GC scheme as it requires scanning all such
hash tables before recycling objects they contain.
Interlisp-D has one case where such "weak links" were removed (or, at
least so was the plan -- I'm not sure if it was ever implemented). The
clever trick was that the incremental Reference Counting garbage collector
could be counted upon to tell you a likely candidate: if an entry for the
key in a hash-table has refcnt of 1, then (modulo stack reconcilation) it
is removeable; because the count of 1 means that that table entry points
to it and no one else does. A "background" process could go around
scavenging over hash-tables, removing inaccessible entries when it found
them (there is no particular need to remove them "instantly", or even
at normal GC time).
But on a broader view, yes, I think Jeff's request is not only reasonable
but very desirable. And I think your assesssment of the problems is
correct -- it will be rather tedious non-portable coding to make it work.
At one time, a bunch of us working of Vax/NIL devised a scheme for such
tables [partly to implement the backwards-compatiblity feature of
MacLisp called MAKNUM]; it required a "hook" in the Stop-and-Copy garbage
collector. But then, the GC for Vax/NIL never got done. The best-laid
plans of mice and men go oftimes a-garbage-collecting.
-- JonL --
∂22-Jul-88 0732 Common-Lisp-mailer hash tables and GC
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 22 Jul 88 07:32:17 PDT
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA24942@EDDIE.MIT.EDU>; Fri, 22 Jul 88 10:30:26 EDT
Received: by spt.entity.com (smail2.5); 22 Jul 88 10:13:34 EDT (Fri)
To: goldman@vaxa.isi.edu
Cc: jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk, common-lisp@sail.stanford.edu
In-Reply-To: goldman@vaxa.isi.edu's message of Thu, 21 Jul 88 09:33:27 PDT <8807211633.AA27307@vaxa.isi.edu>
Subject: hash tables and GC
Message-Id: <8807221013.AA12619@spt.entity.com>
Date: 22 Jul 88 10:13:34 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
Coral will have something like that in the next (major) release, although they
probably will not be presented as hash tables. Letting you map over them is
actually ok, although you have to be aware that just because you put something
in one once doesn't mean it'll still be there when you map over it later.
This isn't much different from do-all-symbols in a lisp which does gctwa.
∂22-Jul-88 0956 RPG Address Change
∂22-Jul-88 0904 unido!gmdzi!jc@uunet.UU.NET Address Change
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 22 Jul 88 09:04:35 PDT
Received: from unido.UUCP by uunet.UU.NET (5.59/1.14) with UUCP
id AA05986; Fri, 22 Jul 88 12:03:25 EDT
Received: by unido.uucp with uucp;
Fri, 22 Jul 88 12:46:09 +0100
Received: by gmdzi.UUCP id AA04682; Fri, 22 Jul 88 13:34:22 -0200
Date: Fri, 22 Jul 88 13:34:22 -0200
From: "Juergen Christoffel" <unido!gmdzi!jc@uunet.UU.NET>
Message-Id: <8807221134.AA04682@gmdzi.UUCP>
To: common-lisp-request@sail.stanford.edu,
cl-windows-request@sail.stanford.edu
Subject: Address Change
Reply-To: unido!sysiphos!jc@uunet.UU.NET
Cc: gmdzi!listmaster@uunet.UU.NET
Hello,
we are on the cl-windows and common-lisp mailing list. Our old address
should be common-lisp-gmd%lispm-1%gmdzi@seismo.css.gov
(cl-windows-gmd%lispm-1%gmdzi@seismo.css.gov) or something similar.
Our NEW ADDRESS is common-lisp@gmdzi.uucp (cl-windows@gmdzi.uucp)
gmdzi is known to most unix hosts running the pathalias s/w. Host
uunet.uu.net might be a good guess to send to, because our whole mail
gets routed through uunet.
I am reachable as
listmaster@gmdzi.uucp
jc@gmdzi.uucp
jc%sysiphos@gmdzi.uucp
We recently had some trouble converting our lisp-machine namespaces to
notice a new primary server machine and due to this messages may have
bounced from here. I apologize for any inconvenience this may have
caused. The mailer behind the new address above (hopefully) will catch
any local errors and redirect them to me.
Regards, JC
Juergen Christoffel Mail: jc@gmdzi.UUCP
German National Research Center Phone: (++49 2241) 14-2421
for Computer Science (GMD),
P.O. Box 1240
D-5205 St. Augustin 1, FRG
∂22-Jul-88 1001 Common-Lisp-mailer hash tables and GC
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 22 Jul 88 10:00:50 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA04035; Fri, 22 Jul 88 09:58:03 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0)
id AA12710; Fri, 22 Jul 88 09:58:40 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA04638; Fri, 22 Jul 88 10:00:21 PDT
Date: Fri, 22 Jul 88 10:00:21 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8807221700.AA04638@lukasiewicz.sun.com>
To: gz@spt.entity.com
Cc: goldman@vaxa.isi.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk,
common-lisp@sail.stanford.edu
In-Reply-To: Gail Zacharias's message of 22 Jul 88 10:13:34 EDT (Fri) <8807221013.AA12619@spt.entity.com>
Subject: hash tables and GC
Date: 22 Jul 88 10:13:34 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
Coral will have something like that in the next (major) release, although they
probably will not be presented as hash tables. Letting you map over them is
actually ok, although you have to be aware that just because you put something
in one once doesn't mean it'll still be there when you map over it later.
Sometimes that's "OK", sometimes not. For example, if a hash table is being
used as a relational database (with a primary key indexed by the hash table),
you probably don't want tuples therein to be GC-able.
Therefore, it's wise not to present them as hash tables.
This isn't much different from do-all-symbols in a lisp which does gctwa.
I believe only the simplest symbols should be GC-ed; if a symbol is
interned and has a nontrivial plist (say), GC-ing it will change
the visible behavior of the program, since if a program re-creates
it (via INTERN or READ), it will be missing its plist.
Similarly, if hash table keys are being used to store information,
as well as merely access it, they shouldn't be GC-ed.
Putting weak links to keys in hash tables would make the EQUAL semantics
I proposed impossible, since an isomorphism test depends strongly
on MAPHASH. (Or, before EQUAL is applied to test for isomorphism,
normalize the two tables by performing a full GC! :@)
Weak pointers are probably more useful than EQUAL isomorphism tests,
but a reliable MAPHASH also seems indispensible. Sounds to me
like weakly-linked keys want to be another option to
MAKE-HASH-TABLE.
-- John
∂22-Jul-88 1134 Common-Lisp-mailer Re: hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 22 Jul 88 11:33:18 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06079; 22 Jul 88 18:27 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Fri, 22 Jul 88 18:23:53 BST
Message-Id: <23883.8807221723@aiai.ed.ac.uk>
To: goldman@vaxa.isi.edu, jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>
Subject: Re: hash tables and GC
Cc: common-lisp@sail.stanford.edu
> From: goldman@edu.isi.vaxa
> Subject: hash tables and GC
> Date: Thu, 21 Jul 88 09:33:27 PDT
> > Apropos of hash tables, one feature of Pop(Log) that I sometimes want
> > to have is "temporary properties". They are essentially hash tables
> > such that being in them does not prevent being garbage collected.
> I'm not sure just what you mean by "being in" a hash table. I have
> commonly seen the following case -- is it what you have in mind?
>
> I have an EQ hash table H. My program will never apply the MAPHASH accessor
> to H. Therefore, the fact that H is accessible to my program does NOT
> imply that any of the keys or values are accessible. If the pair [K V]
> is in the table, then if K is independently accessible, V is also
> accessible. But if K is not independently accessible, it is garbage, and
> so is V unless V is independently accessible.
Yes, that's what I had in mind, except for one thing:
Even if you do a MAPHASH, there is no way for you to tell K should be
in the table (or even that it exists) unless you have independent
access to it. So, the possibility of MAPHASH would still allow K
and V to be removed. Of course, you could gather various statistics
with MAPHASH that would change if K were removed (e.g., the number of
keys would decrease), but I think that's OK.
Indeed, T had something called "populations" (now called "weak sets")
that did not prevent GC of their elements and that supported an
operation call walk-population. They are somewhat less useful that
what I have in mind, though, because all you can ask is whether
something's in the population or not (i.e., whether it's a K --
there's no associated V).
-- Jeff
∂22-Jul-88 1135 Common-Lisp-mailer Re: hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 22 Jul 88 11:34:31 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06246; 22 Jul 88 18:56 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Fri, 22 Jul 88 18:52:15 BST
Message-Id: <23915.8807221752@aiai.ed.ac.uk>
To: gz%spt.entity.com@NSS.Cs.Ucl.AC.UK, jrose@sun.com
Subject: Re: hash tables and GC
Cc: common-lisp@sail.stanford.edu,
jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>
> Date: Fri, 22 Jul 88 10:00:21 PDT
> From: John Rose <jrose@com.sun>
> Sometimes that's "OK", sometimes not. For example, if a hash table is
> being used as a relational database (with a primary key indexed by the
> hash table), you probably don't want tuples therein to be GC-able.
True. There are cases where the "independent reference" is in the
user's head. Some value has been associated with a string key, say,
and it should remain in case the user types it again. So, I'm not
whether "weak retention" makes sense for EQUAL tables; but perhaps
it does nonetheless.
> Therefore, it's wise not to present them as hash tables.
I don't mind calling them something else.
> Similarly, if hash table keys are being used to store information,
> as well as merely access it, they shouldn't be GC-ed.
The question is whether you have any way of getting that key object.
If nothing has a pointer to X, there's no way to know X exists much
less that it's in some table. (I'm thinking EQ here.)
> Putting weak links to keys in hash tables would make the EQUAL semantics
> I proposed impossible, since an isomorphism test depends strongly
> on MAPHASH. (Or, before EQUAL is applied to test for isomorphism,
> normalize the two tables by performing a full GC! :@)
I'm willing to have "EQUAL uncertainty" for "weak tables" if it's
decided that EQUAL traverses such things at all.
> Weak pointers are probably more useful than EQUAL isomorphism tests,
> but a reliable MAPHASH also seems indispensible. Sounds to me
> like weakly-linked keys want to be another option to
> MAKE-HASH-TABLE.
Just so. I did not want all tables to be that way, just for it to
possible to have some that were.
Cheers,
Jeff
Jeff Dalton, JANET: J.Dalton@uk.ac.ed
AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton
∂22-Jul-88 1150 Common-Lisp-mailer hash tables and GC
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 22 Jul 88 11:50:01 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 22 Jul 88 14:50:49 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 22 Jul 88 14:47:11 EDT
Date: Fri, 22 Jul 88 14:48 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: hash tables and GC
To: John Rose <jrose@sun.com>
Cc: gz@spt.entity.com, goldman@vaxa.isi.edu,
jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk,
common-lisp@sail.stanford.edu
In-Reply-To: <8807221700.AA04638@lukasiewicz.sun.com>
Message-Id: <19880722184820.1.BARMAR@OCCAM.THINK.COM>
Date: Fri, 22 Jul 88 10:00:21 PDT
From: jrose@sun.com (John Rose)
Date: 22 Jul 88 10:13:34 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
This isn't much different from do-all-symbols in a lisp which does gctwa.
I believe only the simplest symbols should be GC-ed; if a symbol is
interned and has a nontrivial plist (say), GC-ing it will change
the visible behavior of the program, since if a program re-creates
it (via INTERN or READ), it will be missing its plist.
That's the definition of GCTWA (which stands for GC Truly Worthless
Atoms -- an atom is truly worthless if it is unbound, its function cell
is unbound, its property list is NIL, and the only reference to it is in
a package structure). Such a GC is transparent as long as you don't use
DO-SYMBOLS or its variants and don't look at the second value of INTERN
and FIND-SYMBOL.
Similarly, if hash table keys are being used to store information,
as well as merely access it, they shouldn't be GC-ed.
Putting weak links to keys in hash tables would make the EQUAL semantics
I proposed impossible, since an isomorphism test depends strongly
on MAPHASH. (Or, before EQUAL is applied to test for isomorphism,
normalize the two tables by performing a full GC! :@)
Weak pointers are probably more useful than EQUAL isomorphism tests,
but a reliable MAPHASH also seems indispensible. Sounds to me
like weakly-linked keys want to be another option to
MAKE-HASH-TABLE.
He never said that this would be replacing hash tables; in fact, he said
it probably would NOT use the hash table interfaces. A CL-compatible
hash table can't drop elements into the bit-bucket during GC. This
feature would have to be an extension that would be invoked explicitly
when it is wanted. The definition of EQUAL on GC-able hash tables might
have to be different from that for ordinary hash tables.
barmar
∂22-Jul-88 1221 Common-Lisp-mailer Re: hash tables and GC
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 22 Jul 88 12:21:04 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 22 Jul 88 15:21:57 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 22 Jul 88 15:18:20 EDT
Date: Fri, 22 Jul 88 15:19 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: hash tables and GC
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: goldman@vaxa.isi.edu, jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>,
common-lisp@sail.stanford.edu
In-Reply-To: <23883.8807221723@aiai.ed.ac.uk>
Message-Id: <19880722191930.6.BARMAR@OCCAM.THINK.COM>
Date: Fri, 22 Jul 88 18:23:53 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Even if you do a MAPHASH, there is no way for you to tell K should be
in the table (or even that it exists) unless you have independent
access to it. So, the possibility of MAPHASH would still allow K
and V to be removed. Of course, you could gather various statistics
with MAPHASH that would change if K were removed (e.g., the number of
keys would decrease), but I think that's OK.
That's not quite correct. You could remember some property of the
key, or a value that you expect to find, without retaining independent
access to the key itself. For example,
(defun reverse-gethash (value table)
(let ((keys nil))
(maphash #'(lambda (key val)
(when (eq val value)
(push key keys)))
table)
keys))
In the above example I'm presuming that the GCing we are talking about
would delete entries if there were no other references to the key, and
ignores other references to the value. Here's something that doesn't
depend on this:
(defun gethash-by-pname (string table &optional default)
(maphash #'(lambda (key val)
(when (and (symbolp key) (string-equal (symbol-name key) string))
(return-from gethash-by-pname (values val t)))
table)
(values default nil))
The general point is that MAPHASH allows you to find entries that have
properties other than the one defined by the table's equality predicate.
barmar
∂22-Jul-88 1232 Common-Lisp-mailer hash tables and GC
Received: from EDDIE.MIT.EDU by SAIL.Stanford.EDU with TCP; 22 Jul 88 12:32:44 PDT
Received: by EDDIE.MIT.EDU with UUCP with smail2.5 with sendmail-5.45/4.7 id <AA01371@EDDIE.MIT.EDU>; Fri, 22 Jul 88 15:31:46 EDT
Received: by spt.entity.com (smail2.5); 22 Jul 88 14:41:34 EDT (Fri)
To: jrose@Sun.COM
Cc: common-lisp@sail.stanford.edu
In-Reply-To: John Rose's message of Fri, 22 Jul 88 10:00:21 PDT <8807221700.AA04638@lukasiewicz.sun.com>
Subject: hash tables and GC
Message-Id: <8807221441.AA13220@spt.entity.com>
Date: 22 Jul 88 14:41:34 EDT (Fri)
From: gz@spt.entity.com (Gail Zacharias)
I think you might have misunderstood. These things are a new data type, which
doesn't replace any existing lisp data type. You can't get one without
explicitly asking for it, which you presumably only do if you want the special
behavior it provides. Given that, there's no problem with mapping over them.
In fact doing so is necessary in the primary application we have for them
(keeping track of marks in the editor). The issue about presenting them as
hash tables is simply a question of whether they should be viewed as providing
a mapping between pairs of objects like hash tables do, or simply storing
a set of objects like lists do.
∂22-Jul-88 1717 Common-Lisp-mailer Re: hash tables and GC
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 22 Jul 88 17:17:42 PDT
Posted-Date: Fri, 22 Jul 88 17:17:59 PDT
Message-Id: <8807230018.AA26438@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA26438; Fri, 22 Jul 88 17:18:07 PDT
To: COMMON-LISP@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: Re: hash tables and GC
Date: Fri, 22 Jul 88 17:17:59 PDT
Sender: goldman@vaxa.isi.edu
I may be missing something, but this doesn't look like very complex
semantic issue to me. [Implementation is another matter.] The conditions
under which a hash table key is accessible ONLY via maphash were, I
believe correctly, spelled out in my earlier message. If those conditions
are met, and the program in fact does not do maphash's on the array,
AND (as I neglected to notice earlier) the program does NOT apply
HASH-TABLE-COUNT to the array, then it is SAFE to remove the entry for the
key from the hash table. [SAFE == the program cannot possibly tell that
it has happened.]
As was correctly pointed out, if hash table EQUALity is defined, then the
safety conditions mentioned are no longer sufficient.
In general, I think if a programmer authorizes (whether through
declarations, or extra arguments to a function like MAKE-HASH-TABLE), some
potentially unsafe optimization by the implementation (such as the garbage
collector removing hash table entries), it is VERY desirable to identify
sufficient conditions (such as no uses of maphash and no hash-table-count]
under which the optimization is SAFE and declare that "it is an error",
if the program requesting the optimization violates those conditions.
Of course, these SUFFICIENT conditions may not be NECESSARY, so
some programmers, like those at CORAL, may be astute enough
to write programs that violate the sufficiency conditions but are
nevertheless portable. More power to them. (Or maybe they can state
weaker sufficiency conditions?) But if I were just
presented with some procedural description of an optimization I can request
and NO guidance on when it is safe (just a line that says USE WITH
CAUTION), I would be loathe to try using it at all.
Neil
∂03-Aug-88 1644 Common-Lisp-mailer Removal request
Received: from SPICE.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 3 Aug 88 16:44:43 PDT
Received: from SPICE.CS.CMU.EDU by SPICE.CS.CMU.EDU; 3 Aug 88 19:40:43 EDT
(Message inbox: 32)
To: Common-Lisp@sail.stanford.edu
Subject: Removal request
Date: Wed, 03 Aug 88 19:40:35 EDT
Message-ID: <7820.586654835@SPICE.CS.CMU.EDU>
From: Rick.Busdiecker@SPICE.CS.CMU.EDU
Please remove me from the Common-Lisp mailing list and send me a message
confirming that you have done so. Thank you.
Rick
∂04-Aug-88 0056 Common-Lisp-mailer Hash Tables and GC
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 4 Aug 88 00:55:45 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ac15973; 4 Aug 88 3:44 EDT
Received: from cs.umass.edu by RELAY.CS.NET id aa27618; 4 Aug 88 3:26 EDT
Date: Tue, 2 Aug 88 09:18 EDT
From: ELIOT@cs.umass.edu
Subject: Hash Tables and GC
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: in%"common-lisp@sail.stanford.EDU"
I just got back from vacation and read the discussion of has tables.
One point seems not to have been discussed - "Weak" links in hash
tables would be almost impossible to implement except for EQ hash
tables. Not only does the GC have to prove that the reference
count for both key and value is one, but the GC also has to prove
that there are no other objects, x, such that:
(<Equality-Predicate> x KEY)
For EQ hash tables this condition is true, a priori, but for any
other hash table it is not. Consider an EQL hash table with
BIGNUM keys. A program could somehow effectively copy a bignum
that is being used as a hash table key and then lose the original.
For EQUAL hash tables it is even worse. Suppose (A . B) is a
key. At any time a program might apply CONS to A and B to
re-create the key. For example, suppose I am using a hash
table to represent a graph. If A and B are nodes, then
the graph-links can be implemented using a hash table like this:
(defun BEFORE-P (A B)
(gethash (cons a b) *link-table*))
Even EQ hash tables have problems, in any implementation with
immediate representations for objects. For example the key 57236
(a fixnum) may not be interned and therefor there is no way to tell
how many copies of it exist.
Because of these problems I would suggest that this feature be
restricted to EQ and EQL hash tables, and that numbers of all types
should be considered accessible keys.
∂04-Aug-88 1455 Common-Lisp-mailer [Re: Hash Tables and GC]
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 4 Aug 88 14:55:31 PDT
Posted-Date: Thu, 04 Aug 88 14:55:07 PDT
Message-Id: <8808042155.AA03929@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA03929; Thu, 4 Aug 88 14:55:16 PDT
To: ELIOT@cs.umass.edu
From: goldman@vaxa.isi.edu
Subject: [Re: Hash Tables and GC]
Cc: common-lisp@sail.stanford.edu
In-Reply-To: ELIOT@cs.umass.edu's message of 2795519880
Date: Thu, 04 Aug 88 14:55:07 PDT
Sender: goldman@vaxa.isi.edu
Not only does the GC have to prove that the reference
count for BOTH key and VALUE is one, but the GC also has to prove
that there are no other objects, x, such that:
(<Equality-Predicate> x KEY)
There is no particular concern about whether other pointers to the VALUE
exist; only pointers to members of the KEY's equivalence class. Look at
the problem not as one of GC, but as one of "when is it safe to remove
an entry from a hash table?" [once it has been removed that may make
the value garbage (reduce its reference count to 0)]. It is certainly
SAFE to remove a set of entries Ei= [Ki Vi] if, once the Ei are removed,
there is no way to construct a reference to an object equivalent to any Ki.
If there are references to KEYS from inside VALUES, some schemes may fail
to remove entries that are safe to remove, but this is just like reference
count GCers that fail to reclaim certain circular structures even though
they are garbage. You lose space, but don't get incorrect results.
Even EQ hash tables have problems, in any implementation with
immediate representations for objects. For example the key 57236
(a fixnum) may not be interned and therefor there is no way to tell
how many copies of it exist.
Considering the paragraph of CLTL beginning on pg 77 and continuing to the top
of pg 78, entries in EQ hash tables having integers or characters as the
KEY can serve NO PORTABLE purpose except for usage through
MAPHASH and/or HASH-TABLE-COUNT.
Neil
∂06-Aug-88 0244 Common-Lisp-mailer [Re: Hashables and GC]
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 6 Aug 88 02:44:31 PDT
Received: from relay2.cs.net by RELAY.CS.NET id an13806; 6 Aug 88 5:16 EDT
Received: from cs.umass.edu by RELAY.CS.NET id cq14721; 6 Aug 88 4:56 EDT
Date: Fri, 5 Aug 88 11:01 EDT
From: ELIOT@cs.umass.edu
Subject: [Re: Hashables and GC]
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.EDU"
From: IN%"goldman@vaxa.isi.EDU" 4-AUG-1988 17:57
To: ELIOT@cs.umass.EDU
Subj: [Re: Hash Tables and GC]
Not only does the GC have to prove that the reference
count for BOTH key and VALUE is one, but the GC also has to prove
that there are no other objects, x, such that:
(<Equality-Predicate> x KEY)
There is no particular concern about whether other pointers to the VALUE
exist; only pointers to members of the KEY's equivalence class.
Agreed, but this has nothin gto do with my main point.
Look at
the problem not as one of GC, but as one of "when is it safe to remove
an entry from a hash table?" [once it has been removed that may make
the value garbage (reduce its reference count to 0)]. It is certainly
SAFE to remove a set of entries Ei= [Ki Vi] if, once the Ei are removed,
there is no way to construct a reference to an object equivalent to any Ki.
Everything you say is precisely correct. It is a consequence of what you
say that requires more emphasis. Consider computationally implementing your
phrase "there is no way to construct a reference to an object equivalent to
any Ki." For EQ hash tables this is somewhat straightforward because of:
for-all x, y if (EQ x y) then (x = y)
i.e. there is only one object EQ to any given object. Hence the size of the
set of objects that can be constructed which are equivalent (EQ) to Ki is one.
Now consider any hash table other than an EQ hash table. In this case the
size (cardinality) of the set of objects that can be constructed which are
equivalent (#'TEST) to Ki is (potentially) infinite, except when the Ki are
some type of object for which EQUAL and EQ are the same (most atomic types)
in which case it is still one.
Now whatever unspecified process determines that it is safe to remove the
keys and values must prove that there is no reference to any element
of this potentially infinite set. This is clearly impractical except in
some erratic and implementation specific special cases.
What I am saying is that this feature is basically meaningless whenever
the test is not (effectively) EQ. I don't think Common Lisp should have
features which are never really going to work in any implementation.
On the other hand, when restricted to EQ and EQL hash tables (excluding
numbers/characters) I think this is a reasonable feature. It must
be specified what happens when a Key is an interned but GCTWA symbol.
In fact I think this feature could reasonably be driven down a level, into
MAKE-ARRAY. Consider this proposal, upon which the kind of hash-tables
you want could be implemented.
PROPOSAL: Add to MAKE-ARRAY the keywords :GC-PROTECTING (default T) and :KEY
(default #'IDENTITY). If GC-PROTECTING is NIL and (the KEY of) any element
in the array cannot otherwise be referenced then the GC is allowed to
replace the entire array element with NIL.
=====
The :key argument makes it easy to construct hash tables of the type you
want. The lack of a :test argument avoids the problems I am bothered by.
Arrays are a more basic data structure than hash tables, so this might
have more uses. (The :GC-PROTECTING keyword can be inherited by
make-hash-table too.)
Something like this was proposed while I was implementing the editor for NIL.
It would allow the editor to cache data structures after buffers are killed
or large regions deleted, without entirely preventing the GC from reclaiming
the memory. This cacheing was particularly important because of a
negative temporal displacement in the implementation of the garbage collector.
Christopher Eliot
University of Massachusetts at Amherst
If there are references to KEYS from inside VALUES, some schemes may fail
to remove entries that are safe to remove, but this is just like reference
count GCers that fail to reclaim certain circular structures even though
they are garbage. You lose space, but don't get incorrect results.
Even EQ hash tables have problems, in any implementation with
immediate representations for objects. For example the key 57236
(a fixnum) may not be interned and therefor there is no way to tell
how many copies of it exist.
Considering the paragraph of CLTL beginning on pg 77 and continuing to the top
of pg 78, entries in EQ hash tables having integers or characters as the
KEY can serve NO PORTABLE purpose except for usage through
MAPHASH and/or HASH-TABLE-COUNT.
Neil
∂09-Aug-88 0943 Common-Lisp-mailer request
Received: from Boa-Constrictor.Stanford.EDU by SAIL.Stanford.EDU with TCP; 9 Aug 88 09:43:17 PDT
Received: by Boa-Constrictor.Stanford.EDU.stanford.edu (4.0/SMI-DDN)
id AA08892; Tue, 9 Aug 88 09:37:43 PDT
Date: Tue, 9 Aug 88 09:37:43 PDT
From: binford@Boa-Constrictor.stanford.edu (Tom Binford)
Message-Id: <8808091637.AA08892@Boa-Constrictor.Stanford.EDU.stanford.edu>
To: common-lisp@sail
Subject: request
Please include me on the mailing list.
Tom Binford
∂11-Aug-88 1444 X3J13-mailer CLOS workshop
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Aug 88 14:44:23 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 11 AUG 88 14:38:15 PDT
Date: Thu, 11 Aug 88 14:33 PDT
From: Gregor.pa@Xerox.COM
Subject: CLOS workshop
To: Common-Lisp@Sail.Stanford.edu, CommonLoops.pa@Xerox.COM,
X3J13@Sail.Stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest
Message-ID: <19880811213330.2.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This is the second announcement of the CLOS workshop to be held at PARC
October 3rd and 4th. This is a reminder to help us with our planning by
letting us know soon if you are planning to attend. My apologies to
people who receive multiple copies of this message.
To clarify the position paper requirement, the workshop is not limited
exclusively to those who have extensive experience writing CLOS code.
Anyone planning CLOS implementations, extensions, environments or CLOS
based application development is encouraged to attend. A position paper
can simply be a description of the kinds of issues you feel should the
CLOS community should address at the workshop.
Workshop for CLOS Users and Implementors
October 3rd and 4th
Xerox PARC
Palo Alto, California
We have been excited by the extent to which CLOS is already being
used, and the ways in which it is being extended. The purpose of
this workshop is to provide an opportunity for the members of the
CLOS community to get together and share their experience.
To provide a good start for the interchange, we are requesting that
participants supply a short position paper (1-3 pages) describing
work related to CLOS. Some topics of interest are:
Applications
Programming Techniques
Implementation
Programming Environment Tools
Extensions of CLOS
Techniques for Converting to CLOS
Meta Object Techniques and Theory
Critiques
We will try to support demonstrations or videotapes of applications,
programming environments, implementations or other relevant systems.
If you are planning to attend, please let us know by August 15th.
This will help us with planning and allow us to arrange a discount
rate at a local hotel.
Position papers should reach us by September 9th so that we can
organize a program and arrange for duplication of the papers.
Position papers, notice to attend, and other correspondence should
be sent to:
Gregor Kiczales
3333 Coyote Hill Rd.
Palo Alto, CA 94304
or by Internet mail to:
Gregor.pa@Xerox.com
-------
∂11-Aug-88 1607 X3J13-mailer CLOS workshop
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 11 Aug 88 14:44:23 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 11 AUG 88 14:38:15 PDT
Date: Thu, 11 Aug 88 14:33 PDT
From: Gregor.pa@Xerox.COM
Subject: CLOS workshop
To: Common-Lisp@Sail.Stanford.edu, CommonLoops.pa@Xerox.COM,
X3J13@Sail.Stanford.edu
Fcc: BD:>Gregor>mail>outgoing-mail-3.text.newest
Message-ID: <19880811213330.2.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
This is the second announcement of the CLOS workshop to be held at PARC
October 3rd and 4th. This is a reminder to help us with our planning by
letting us know soon if you are planning to attend. My apologies to
people who receive multiple copies of this message.
To clarify the position paper requirement, the workshop is not limited
exclusively to those who have extensive experience writing CLOS code.
Anyone planning CLOS implementations, extensions, environments or CLOS
based application development is encouraged to attend. A position paper
can simply be a description of the kinds of issues you feel should the
CLOS community should address at the workshop.
Workshop for CLOS Users and Implementors
October 3rd and 4th
Xerox PARC
Palo Alto, California
We have been excited by the extent to which CLOS is already being
used, and the ways in which it is being extended. The purpose of
this workshop is to provide an opportunity for the members of the
CLOS community to get together and share their experience.
To provide a good start for the interchange, we are requesting that
participants supply a short position paper (1-3 pages) describing
work related to CLOS. Some topics of interest are:
Applications
Programming Techniques
Implementation
Programming Environment Tools
Extensions of CLOS
Techniques for Converting to CLOS
Meta Object Techniques and Theory
Critiques
We will try to support demonstrations or videotapes of applications,
programming environments, implementations or other relevant systems.
If you are planning to attend, please let us know by August 15th.
This will help us with planning and allow us to arrange a discount
rate at a local hotel.
Position papers should reach us by September 9th so that we can
organize a program and arrange for duplication of the papers.
Position papers, notice to attend, and other correspondence should
be sent to:
Gregor Kiczales
3333 Coyote Hill Rd.
Palo Alto, CA 94304
or by Internet mail to:
Gregor.pa@Xerox.com
-------
∂16-Aug-88 1239 Common-Lisp-mailer A Quick Note on the Last L&FP Conference
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 16 Aug 88 12:39:03 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA26479; Tue, 16 Aug 88 13:37:41 MDT
Received: by cons.utah.edu (5.54/utah-2.0-leaf)
id AA22021; Tue, 16 Aug 88 13:37:35 MDT
Date: Tue, 16 Aug 88 13:37:35 MDT
From: kessler%cons@cs.utah.edu (Robert R. Kessler)
Message-Id: <8808161937.AA22021@cons.utah.edu>
To: common-lisp@sail.stanford.edu, scheme@mc.lcs.mit.edu, fp@cs.yale.edu
Cc: dswise@iuvax.cs.indiana.edu
Subject: A Quick Note on the Last L&FP Conference
One of the rumblings that I heard at the conference was that a number
of people didn't receive their copies of the Advance Program mailing
from ACM. Thus, it made it more difficult to register. If any of you
are members of SIGPLAN, SIGART, or SIGACT and you did not receive a
copy of the program some time in May, would you please send David Wise
a message (dswise@iuvax.cs.indiana.edu). He is trying to collect
actual data on the hits and misses of the mailing. Please send him
your name, mailing address at which you receive ACM materials, and
your ACM number if you have it.
Thanks.
Bob.
∂21-Aug-88 0047 Common-Lisp-mailer negative values for the :COUNT keyord argument
Received: from DST.BOLTZ.CS.CMU.EDU ([128.2.220.61]) by SAIL.Stanford.EDU with TCP; 21 Aug 88 00:47:34 PDT
Received: from DST.BOLTZ.CS.CMU.EDU by DST.BOLTZ.CS.CMU.EDU; 21 Aug 88 03:46:04 EDT
To: common-lisp@sail.stanford.edu
Reply-To: Dave.Touretzky@cs.cmu.edu
Subject: negative values for the :COUNT keyord argument
Date: Sun, 21 Aug 88 03:45:56 EDT
Message-ID: <5787.588152756@DST.BOLTZ.CS.CMU.EDU>
From: Dave.Touretzky@B.GP.CS.CMU.EDU
According to the way I read CLtL (pages 247 and 253), a negative value for
the :COUNT keyword, e.g., to REMOVE, is legal and should behave the same as
zero:
(remove #\a "Banana" :count -10) ==> "Banana"
Apparently, not everyone shares this view.
CMU Common Lisp treats negative values like NIL:
* (remove #\a "Banana" :count -10)
"Bnn"
The June 3, 1987 version of KCL treats a negative value as how many spaces
to tack on to the end of the string. It appears to handle lists correctly,
but not vectors:
> (remove #\a "Banana: :count -10)
"Banana "
> (remove 'a '(b a n a n a) :count -10
(B A N A N A)
> (remove 'a '#(b a n a n a) :count -2)
(B A N A N A NIL NIL)
I don't see anything in the manual to indicate that it "is an error" to
supply negative values for the :COUNT keyword. Anybody want to rule on
what the legal behavior is in this case?
-- Dave
∂21-Aug-88 1238 Common-Lisp-mailer Re: negative values for the :COUNT keyord argument
Received: from SEF1.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 21 Aug 88 12:38:38 PDT
Received: from SEF1.SLISP.CS.CMU.EDU by SEF1.SLISP.CS.CMU.EDU; 21 Aug 88 15:37:02 EDT
To: Dave.Touretzky@cs.cmu.edu
cc: common-lisp@sail.stanford.edu
Subject: Re: negative values for the :COUNT keyord argument
In-reply-to: Your message of Sun, 21 Aug 88 03:45:56 -0400.
<5787.588152756@DST.BOLTZ.CS.CMU.EDU>
Date: Sun, 21 Aug 88 15:36:55 EDT
From: Scott.Fahlman@B.GP.CS.CMU.EDU
I cannot find anything in the manual that restricts the range of the :COUNT
keyword to non-negative integers, but I'm sure that's what the legal range
would have been if we had been more systematic about specifying these
things. As it is, a very strict reading of the language in CLtL probably
would imply that a negative count is treated as "remove nothing", though
some might argue that logically this should add a few random occurrences of
what otherwise would have been removed.
I think it's best in such cases to assume that "is an error" is the proper
interpretation. If you feel that "is an error" is not the right
choice here, a proposal to the X3J13 cleanup committee would be in order.
-- Scott
∂22-Aug-88 1034 Common-Lisp-mailer
Received: from xenurus.gould.com by SAIL.Stanford.EDU with TCP; 22 Aug 88 10:34:02 PDT
Received: from vger (vger.Urbana.Gould.COM) by xenurus.gould.com (5.54/)
Date: Mon, 22 Aug 88 12:27:03 CDT
From: zimmerm%vger@xenurus.gould.com (Bruce A. Zimmerman)
Received: by vger (5.54/)
Message-Id: <8808221727.AA09134@vger>
To: AIList@sri.com, COMMON-LISP@sail.stanford.edu,
INFO-AMIGA@red.rutgers.edu.arpa.NOTFOUND, NL-KR@cs.rochester.edu,
NeWs-makers@brillig.umd.edu, bind-request@ucbarpa.berkeley.edu,
gouldbugs@brl.arpa, laser-lovers@brillig.umd.edu,
xport@athena.mid.edu.NOTFOUND
Due to a recent spat of trouble with our internet link we may have bounced
some mail back to you. Please be advised we are alive and well and our link
is up and running again. If you have turned us off in you mailing list please
add us again. Thanks for your attention to this matter.
Bruce Zimmerman
bzimmerman@xenurus.gould.com
OLD ADDR gswd.vms
systems admin
Urbana CSD, Gould inc.
1101 E. University ave.
Urbana, Illinois.
217 384 8500
∂24-Aug-88 1214 Common-Lisp-mailer
Received: from xenurus.gould.com by SAIL.Stanford.EDU with TCP; 24 Aug 88 12:14:06 PDT
Received: from vger (vger.Urbana.Gould.COM) by xenurus.gould.com (5.54/)
Date: Wed, 24 Aug 88 14:03:18 CDT
From: notes%vger@xenurus.gould.com (DCS note file system)
Received: by vger (5.54/)
Message-Id: <8808241903.AA14769@vger>
To: COMMON-LISP@sail.stanford.edu
Due to a recent spat of trouble with our internet link we may have bounced
some mail back to you. Please be advised we are alive and well and our link
is up and running again. If you have turned us off in you mailing list please
add us again. Thanks for your attention to this matter.
Bruce Zimmerman
bzimmerman@xenurus.gould.com
OLD ADDR gswd.vms.arpa
systems admin
Urbana CSD, Gould inc.
1101 E. University ave.
Urbana, Illinois.
217 384 8500
∂24-Aug-88 1215 Common-Lisp-mailer
Received: from xenurus.gould.com by SAIL.Stanford.EDU with TCP; 24 Aug 88 12:15:11 PDT
Received: from vger (vger.Urbana.Gould.COM) by xenurus.gould.com (5.54/)
Date: Wed, 24 Aug 88 14:03:18 CDT
From: notes%vger@xenurus.gould.com (DCS note file system)
Received: by vger (5.54/)
Message-Id: <8808241903.AA14769@vger>
To: COMMON-LISP@sail.stanford.edu
Due to a recent spat of trouble with our internet link we may have bounced
some mail back to you. Please be advised we are alive and well and our link
is up and running again. If you have turned us off in you mailing list please
add us again. Thanks for your attention to this matter.
Bruce Zimmerman
bzimmerman@xenurus.gould.com
OLD ADDR gswd.vms.arpa
systems admin
Urbana CSD, Gould inc.
1101 E. University ave.
Urbana, Illinois.
217 384 8500
∂25-Aug-88 1356 Common-Lisp-mailer READ and "illegal" characters
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 25 Aug 88 13:56:16 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa06487; 25 Aug 88 16:11 EDT
Received: from draper.com by RELAY.CS.NET id aa06669; 25 Aug 88 15:59 EDT
Date: Thu, 25 Aug 88 13:36 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: READ and "illegal" characters
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.edu",SEB1525
Taking the description of the CL reader at face value, I infer that an
"illegal" character may occur in a symbol name if it is preceded by a
backslash ("single escape"), but not if it occurs inside a pair of
vertical bars ("multiple escape"). This seems strange. Is it merely
an oversight, or is it intentional?
This is a potentially significant problem, because it mandates that the
printer must slashify "illegal" characters by preceding each one
individually with a backslash rather than being able to just surround
the entire name with vertical bars. For some implementations (i.e. mine),
it is easier to embar the entire name, once it is determined that funny
characters are present somewhere in the name.
Is it intended that all characters not listed in the table as consituent,
macro, etc. are "illegal"? Or might an implementation be able to treat
them all as constituent characters?
∂25-Aug-88 1715 Common-Lisp-mailer negative values for the :COUNT keyord argument
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 25 Aug 88 17:15:27 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 450862; Thu 25-Aug-88 20:14:00 EDT
Date: Thu, 25 Aug 88 20:14 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: negative values for the :COUNT keyord argument
To: Dave.Touretzky@cs.cmu.edu
cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <5787.588152756@DST.BOLTZ.CS.CMU.EDU>
Message-ID: <19880826001409.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Sun, 21 Aug 88 03:45:56 EDT
From: Dave.Touretzky@B.GP.CS.CMU.EDU
The June 3, 1987 version of KCL treats a negative value as how many spaces
to tack on to the end of the string. It appears to handle lists correctly,
but not vectors:
> (remove #\a "Banana: :count -10)
"Banana "
Does this mean that in KCL (remove #\n "Banana: :count 3) returns a
string that is one character too short? I.e. is it dead-reckoning
the length of the returned string, instead of counting the number of
items that actually will be removed?
∂25-Aug-88 2242 Common-Lisp-mailer proposals regarding :COUNT keyword
Received: from DST.BOLTZ.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 25 Aug 88 22:42:17 PDT
Received: from DST.BOLTZ.CS.CMU.EDU by DST.BOLTZ.CS.CMU.EDU; 26 Aug 88 01:39:52 EDT
To: common-lisp@sail.stanford.edu
Reply-To: Dave.Touretzky@cs.cmu.edu
Subject: proposals regarding :COUNT keyword
Date: Fri, 26 Aug 88 01:39:35 EDT
Message-ID: <9440.588577175@DST.BOLTZ.CS.CMU.EDU>
From: Dave.Touretzky@B.GP.CS.CMU.EDU
I approve of KMP's revision of my original proposal, and appreciate the
time he took to extend it and rewrite it in proper format.
In answer to Moon's question: no, KCL isn't dead-reckoning the length of
the list for positive values of :COUNT. It only messes up for negative
values. Using the June 3, 1987 release of KCL I got the following
behavior:
(remove #\a "Banana" :count 3) ==> "Bnn" ;Correct.
(remove #\a "Banana" :count 4) ==> "Bnn" ;Correct.
(remove #\a "Banana" :count -3) ==> "Banana " ;It's padding!
(remove #\a "Banana" :count -4) ==> "Bannana " ;More padding.
-- Dave
∂26-Aug-88 0759 Common-Lisp-mailer negative values for the :COUNT keyord argument
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 26 Aug 88 07:59:16 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 26 Aug 88 10:55:26 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 26 Aug 88 10:57:31 EDT
Date: Fri, 26 Aug 88 10:57 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: negative values for the :COUNT keyord argument
To: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Cc: Dave.Touretzky@cs.cmu.edu, common-lisp@sail.stanford.edu
In-Reply-To: <19880826001409.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-Id: <19880826145742.3.BARMAR@OCCAM.THINK.COM>
Date: Thu, 25 Aug 88 20:14 EDT
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Date: Sun, 21 Aug 88 03:45:56 EDT
From: Dave.Touretzky@B.GP.CS.CMU.EDU
The June 3, 1987 version of KCL treats a negative value as how many spaces
to tack on to the end of the string. It appears to handle lists correctly,
but not vectors:
> (remove #\a "Banana: :count -10)
"Banana "
Does this mean that in KCL (remove #\n "Banana: :count 3) returns a
string that is one character too short? I.e. is it dead-reckoning
the length of the returned string, instead of counting the number of
items that actually will be removed?
I assume you meant :COUNT 4 (since there are 3 a's in "banana"). In any
case, it seems to do the right thing when :COUNT is positive.
barmar
∂27-Aug-88 1917 Common-Lisp-mailer Standard total ordering
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 27 Aug 88 19:16:35 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04194; 27 Aug 88 21:21 BST
Date: Sat, 27 Aug 88 21:44:19 BST
Message-Id: <2624.8808272044@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Standard total ordering
To: common-lisp@sail.stanford.edu
In Prolog, there is a standard total ordering for terms (i.e., all
data). This is often quite useful. For example, it is faster to
search an ordered list for membership than to search an unordered
one.
Note that the order is essentially arbitrary: what matters is that any
terms may be consistently compared. (OK, what really matters is all
the properties of a total order.)
To what extent is it possible to do something like this for Lisp?
In a Lisp where objects never move (or never change order relative to
each other), the object's address could be used. This assumes we are
ordering objects as distinguished by EQ. Is there some point in
ordering for EQUAL objects instead?
Jeff Dalton, JANET: J.Dalton@uk.ac.ed
AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton
∂27-Aug-88 1917 Common-Lisp-mailer Re: hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 27 Aug 88 19:12:12 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04124; 27 Aug 88 21:03 BST
Date: Sat, 27 Aug 88 21:25:34 BST
Message-Id: <2583.8808272025@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: hash tables and GC
To: barmar@think.com
Cc: common-lisp@sail.stanford.edu
Now that mail on this topic has quieted down, I would like to try to
summarize. My original message suggested that something like Pop11's
"temporary properties" would be useful in Common Lisp, and said that
temporary properties were similar to hash tables except that being
in one did not prevent GC. This left imprecise such things as the
meaning of "in".
What I had in mind was this: Consider an EQ hash table. I can keep
track of some property of objects by entering the objects as keys in
a hash table. There is, however, an unfortunate side effect: the
keys cannot be garbage collected until the table is. I suspect
this greatly restricts the cases in which hash tables can be used.
For example, one way to associate new information with an object would
be to use CLOS to define a subclass of the object's class. The
subclass would have one additional slot, and you could call CHANGE-CLASS
to add that slot to a given object. In this case, the association
would not affect the collectibility of the object. However, there may
be times when you would rather not make the new information be part of
the object (or when you can't because the object isn't of a kind that
can have its class changed). It might seem that you could use a hash
table. But since objects have indefinite lifetimes, the hash table
has to stay around more or less forever, and then the objects have to
stay around forever too.
[Suppose you implement SYMBOL-PLIST using a hash table instead of a
slot that's part of each symbol. This seems reasonable until you
notice that then no symbol with a plist -- interned or not --
could ever be collected.]
It's probably best to have a concrete proposal, so I'll make one:
Add a keyword parameter :TEMPORARY to MAKE-HASH-TABLE. If this
argument is specified and not NIL, and if :TEST is #'EQ or #'EQL,
entries in the table may be removed by the GC if the key (i.e.,
an object EQ or EQL to the key) is accessible only through the
table(*). Entries in EQUAL tables are never so removed, nor are
numbers in EQL tables. [Explanation: in these cases, it is
generally possible to construct new objects that are respectively
EQUAL or EQL to the key.]
(*) Actually, I think this should be "accessible only through
such tables", because something might be in more than one.
Current practice:
Pop11 has a similar capability as "temporary properties".
(For this purpose, we can think of Pop as Lisp with a different
syntax.)
T has "weak sets". T also has OBJECT-HASH and OBJECT-UNHASH,
which use "weak pointers". If (OBJECT-HASH object) => i, then
(OBJECT-UNHASH i) => object if the object is still accessible
and false if it is not. i is an integer.
R2RS Scheme also has OBJECT-HASH and OBJECT-UNHASH, but they
were not "essential" and have since been removed.
Issues:
0. Can such tables be implemented?
It seems possible that some GC methods might have difficulty,
but no one has mentioned anything that makes temporary entries
impossible (or even impractical).
Note that since CL does not require any GC at all, it probably
cannot require that entries ever actually vanish (even if there
is a GC).
1. Tables or sets?
For some applications, all that's required is a "set" of objects
that might be used (or reused) if they still exist. This is
equivalent to a table where the value for a key is always T or
NIL but is simpler and requires less storage. Moreover, temporary
table entries can be implemented, given such "weak sets", by
occasionally going through the table and removing entries whose
keys are not still in the set.
Minimalists may therefore prefer sets; pragmatists will tend to favor
tables because they're more generally useful.
2. Hash tables or a new kind of table?
There is some reason to say that adding a new feature to hash tables
is not the best solution. In particular, there are problems with EQL
and EQUAL tables. However, a new kind of table would most likely be
so similar to a hash table that it might as well *be* a hash table.
This dilemma could be considered an argument for sets instead of
tables.
Specific alternatives:
* Instead of a keyword argument to MAKE-HASH-TABLE, have a separate
constructor, MAKE-PROPERTY-TABLE, say. This implies that, instead
of property-table being a subtype of hash-table, hash- and property-
tables would both be subtypes of a type table.
However, it is difficult to come up with a good name for these things,
and I find this relationship between the two types of table less
natural than adding a new dimension to hash tables.
* Have a keyword argument to MAKE-ARRAY. [This was suggested by
Christopher Eliot <ELIOT@edu.umass.cs>, who also suggested the
keyword :GC-PROTECTING.] Membership in an array is, of course,
by EQ, thus avoiding questions about EQL and EQUAL. Such arrays
would be a kind of "weak set".
I do not think such arrays would be very useful as-is because
they would require a linear search for membership.
3. What about EQL and EQUAL hash tables?
It does not make much sense to have temporary entries in EQUAL hash
tables. Suppose an entry could be removed if there were no accessible
objects EQUAL to the key. This is not a condition that it is practical
to test. Nor is it sufficient: it is often possible to create new
EQUAL objects, and so the entry should remain unless it is not
possible to create new EQUAL objects.
EQL tables share this problem, because it is always possible to create
a new EQL number. Nonetheless, any entry that was not a number could
be subject to collection as in EQ tables.
Well, what about numbers in EQ tables? What about numbers that are
represented directly rather than given storage of their own? Such
problems already exist for EQ hash tables and are not (I think) made
noticeably worse by the addition of temporary entries. (Suppose
you have a number. How do you know *that number* is in an EQ
hash table?)
4. Pointers to the value.
In several messages, it was suggested (or assumed) that a table entry
would not be removed unless both the key and its associated value
could be collected. Against this notion, I would cite the following:
(1) The key and value are not symmetric (hash tables are mappings
from keys to values) and so it is reasonable to treat them differently.
(2) Tables in which only the key need be inaccessible are more useful --
often the value will be something like T or NIL that will have a
lifetime at least as long as the table's.
5. The implications of MAPHASH.
> Date: Fri, 22 Jul 88 15:19 EDT
> From: Barry Margolin <barmar@com.think>
>
> Date: Fri, 22 Jul 88 18:23:53 BST
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
>
> Even if you do a MAPHASH, there is no way for you to tell K should be
> in the table (or even that it exists) unless you have independent
> access to it. So, the possibility of MAPHASH would still allow K
> and V to be removed. Of course, you could gather various statistics
> with MAPHASH that would change if K were removed (e.g., the number of
> keys would decrease), but I think that's OK.
>
> That's not quite correct. You could remember some property of the
> key, or a value that you expect to find, without retaining independent
> access to the key itself. [...]
>
> (defun gethash-by-pname (string table &optional default)
> (maphash #'(lambda (key val)
> (when (and (symbolp key)
> (string-equal (symbol-name key) string))
> (return-from gethash-by-pname (values val t)))
> table)
> (values default nil))
>
> The general point is that MAPHASH allows you to find entries that have
> properties other than the one defined by the table's equality predicate.
OK, but assuming some key K has pname S and you have no pointer to K
other then the entry in the hash table, all your program can know is
that some key has (well, had) pname S, not that K was in the table.
To know that K (up to EQ) is in the table, you have to have a pointer
to K.
Jeff Dalton, JANET: J.Dalton@uk.ac.ed
AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton
∂29-Aug-88 0908 Common-Lisp-mailer Re: hash tables and GC
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 29 Aug 88 09:08:51 PDT
Received: from KOYAANISQATSI.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213034; Mon 29-Aug-88 12:08:03 EDT
Date: Mon, 29 Aug 88 12:06 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
cc: barmar@THINK.COM, common-lisp@sail.stanford.edu, DLA@JASPER.SCRC.Symbolics.COM
In-Reply-To: <2583.8808272025@subnode.aiai.ed.ac.uk>
Message-ID: <19880829160631.8.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Date: Sat, 27 Aug 88 21:25:34 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
...
It's probably best to have a concrete proposal, so I'll make one:
Add a keyword parameter :TEMPORARY to MAKE-HASH-TABLE. If this
argument is specified and not NIL, and if :TEST is #'EQ or #'EQL,
entries in the table may be removed by the GC if the key (i.e.,
an object EQ or EQL to the key) is accessible only through the
table(*). Entries in EQUAL tables are never so removed, nor are
numbers in EQL tables. [Explanation: in these cases, it is
generally possible to construct new objects that are respectively
EQUAL or EQL to the key.]
(*) Actually, I think this should be "accessible only through
such tables", because something might be in more than one.
Current practice:
Pop11 has a similar capability as "temporary properties".
(For this purpose, we can think of Pop as Lisp with a different
syntax.)
T has "weak sets". T also has OBJECT-HASH and OBJECT-UNHASH,
which use "weak pointers". If (OBJECT-HASH object) => i, then
(OBJECT-UNHASH i) => object if the object is still accessible
and false if it is not. i is an integer.
R2RS Scheme also has OBJECT-HASH and OBJECT-UNHASH, but they
were not "essential" and have since been removed.
Issues:
0. Can such tables be implemented?
Proof by existence: We have had such tables prototyped internally at
Symbolics for a year or so, but have not had the resources to qualify
them for release to customers. They can be quite efficient, and of
course can significantly improve the efficiency of some kinds of
programs.
∂29-Aug-88 2104 Common-Lisp-mailer Re: hash tables and GC
Received: from EMS.MEDIA.MIT.EDU (EMS.MIT.EDU) by SAIL.Stanford.EDU with TCP; 29 Aug 88 21:04:40 PDT
Received: by EMS.MEDIA.MIT.EDU (5.54/4.8) id AA03125; Tue, 30 Aug 88 00:03:57 EDT
Date: Tue, 30 Aug 88 00:03:57 EDT
From: smh@EMS.MEDIA.MIT.EDU (Steven Haflich)
Message-Id: <8808300403.AA03125@EMS.MEDIA.MIT.EDU>
To: common-lisp@sail.stanford.edu
Subject: Re: hash tables and GC
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
0. Can such tables be implemented?
Proof by existence: We have had such tables prototyped internally at
Symbolics for a year or so, but have not had the resources to qualify
them for release to customers. They can be quite efficient, and of
course can significantly improve the efficiency of some kinds of
programs.
But perhaps this isn't exactly the right question for such a late date
in the CL standards process. Rather:
Can such tables be implemented with reasonable performance
in *all* existing CL implementations, without breaking the GC
strategies upon which they depend?
I myself have no idea which way this question would fall, but unless
it could confidently be answered in the affirmative I feel X3J13 would
have to exclude these `weak-pointer' tables from the standard. The
*real* problem is that it would be incumbent on the *proposer* to
prove practicality. This would not be an easy proof.
∂29-Aug-88 2236 Common-Lisp-mailer Re: hash tables and GC
Received: from EMS.MEDIA.MIT.EDU (EMS.MIT.EDU) by SAIL.Stanford.EDU with TCP; 29 Aug 88 21:04:40 PDT
Received: by EMS.MEDIA.MIT.EDU (5.54/4.8) id AA03125; Tue, 30 Aug 88 00:03:57 EDT
Date: Tue, 30 Aug 88 00:03:57 EDT
From: smh@EMS.MEDIA.MIT.EDU (Steven Haflich)
Message-Id: <8808300403.AA03125@EMS.MEDIA.MIT.EDU>
To: common-lisp@sail.stanford.edu
Subject: Re: hash tables and GC
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
0. Can such tables be implemented?
Proof by existence: We have had such tables prototyped internally at
Symbolics for a year or so, but have not had the resources to qualify
them for release to customers. They can be quite efficient, and of
course can significantly improve the efficiency of some kinds of
programs.
But perhaps this isn't exactly the right question for such a late date
in the CL standards process. Rather:
Can such tables be implemented with reasonable performance
in *all* existing CL implementations, without breaking the GC
strategies upon which they depend?
I myself have no idea which way this question would fall, but unless
it could confidently be answered in the affirmative I feel X3J13 would
have to exclude these `weak-pointer' tables from the standard. The
*real* problem is that it would be incumbent on the *proposer* to
prove practicality. This would not be an easy proof.
∂30-Aug-88 0952 Common-Lisp-mailer READ and "illegal" characters
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Aug 88 09:51:32 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 452311; Tue 30-Aug-88 12:47:10 EDT
Date: Tue, 30 Aug 88 12:46 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: READ and "illegal" characters
To: SEB1525@draper.com, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: The message of 25 Aug 88 13:36 EDT from "Steve Bacher (Batchman)" <SEB1525@draper.com>
Message-ID: <19880830164657.2.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Thu, 25 Aug 88 13:36 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Taking the description of the CL reader at face value, I infer that an
"illegal" character may occur in a symbol name if it is preceded by a
backslash ("single escape"), but not if it occurs inside a pair of
vertical bars ("multiple escape"). This seems strange. Is it merely
an oversight, or is it intentional?
There appear to be two types of "illegal" characters - (a) a character
with an "illegal" syntax type, or (b) a constituent character with an
"illegal" attribute.
Only illegal characters of type (b) are specified in the manual. Since
it is impossible for a programmer to explicitly specify the syntactic
type of a character (you can only copy it by set-syntax-from-char), it
is up to the implementors to allow, or disallow an "illegal" syntactic
type (type (a) illegal characters) in their implementation.
Step 9 on page 337 specifically says that the reader performs "one of
the following actions" according to the character's >syntactic< type.
If you want multiple escapes to behave identically to single escapes,
you can choose to make no characters with "illegal" syntactic type.
(Make them all whitespace, or constituent with an "illegal" attribute)
This finesses the question of whether CLtL means to treat single and
multiple-escapes differently. But it does mean that the question isn't
>significant<.
Notice, though, that portability of printed representation isn't an
issue here, because none of the standard characters have an "illegal"
syntax type.
This is a potentially significant problem, because it mandates that the
printer must slashify "illegal" characters by preceding each one
individually with a backslash rather than being able to just surround
the entire name with vertical bars. For some implementations (i.e. mine),
it is easier to embar the entire name, once it is determined that funny
characters are present somewhere in the name.
Is it intended that all characters not listed in the table as consituent,
macro, etc. are "illegal"? Or might an implementation be able to treat
them all as constituent characters?
I believe the latter must be correct, (the implementor can choose the
syntactic type of all non-standard characters), otherwise it would be
impossible to read in symbols in (for example) Japanese.
∂30-Aug-88 1636 Common-Lisp-mailer RE: Read and "illegal" characters
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 30 Aug 88 16:36:45 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa05497; 30 Aug 88 19:03 EDT
Received: from draper.com by RELAY.CS.NET id ab15253; 30 Aug 88 18:50 EDT
Date: Tue, 30 Aug 88 16:37 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: RE: Read and "illegal" characters
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.edu",SEB1525
Yes, (a) is what I meant - the syntactic property of the character,
not the attribute used in scanning atom names.
∂30-Aug-88 2214 Common-Lisp-mailer RE: Read and "illegal" characters
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 30 Aug 88 22:14:38 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 452687; Wed 31-Aug-88 01:13:35 EDT
Date: Wed, 31 Aug 88 01:13 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: RE: Read and "illegal" characters
To: SEB1525@draper.com, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: The message of 30 Aug 88 16:37 EDT from "Steve Bacher (Batchman)" <SEB1525@draper.com>
Message-ID: <19880831051323.5.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Tue, 30 Aug 88 16:37 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Yes, (a) is what I meant - the syntactic property of the character,
not the attribute used in scanning atom names.
Then I believe that you are in luck.
To recap:
There are no standard characters that are syntactically "illegal",
therefore no characters that *must* behave differently between single
and multiple escapes.
There is no CL sanctified way to set the syntax of a character, only to
copy the syntax.
Further, I believe it is legal for you, as a language implementor, to
define the syntax of a character. So you are free to ensure that in your
implementation, no characters have an "illegal syntactic type".
Instead, define characters you want to outlaw as "constituents" with just
the "illegal" attribute. There is now no way to create the problem
characters.
As I said before, this finesses the practical problem, but does not
solve the academic problem. My personal hope is that the distinction
between single and multiple-escapes is unintentional. The 2 paragraphs
on pg 338 seems to support this:
"As a rule, a @i(single escape) character never stands for itself but
always serves to cause the following character to be treated as a simple
alphabetic character. A @i(single escape) character can be included in
a token only if preceded by another @i(single escape) character.
A @i(multiple escape) character also never stands for itself. The
characters between a pair of @i(multiple escape) characteres are all
treated as simple alphabetic characrters, except that @i(single escape)
and @i(multiple escape) characters must nevertheless be preceded by a
@i(single escape) character to be included."
Perhaps the cleanup committee has dealt with this issue already. I
don't know.
∂31-Aug-88 1806 Common-Lisp-mailer Re: hash tables and GC
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 31 Aug 88 18:06:10 PDT
Received: from KOYAANISQATSI.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213799; Wed 31-Aug-88 21:05:29 EDT
Date: Wed, 31 Aug 88 21:03 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
To: smh@EMS.MEDIA.MIT.EDU
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8808300403.AA03125@EMS.MEDIA.MIT.EDU>
Message-ID: <19880901010347.3.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Date: Tue, 30 Aug 88 00:03:57 EDT
From: smh@EMS.MEDIA.MIT.EDU (Steven Haflich)
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
0. Can such tables be implemented?
Proof by existence: We have had such tables prototyped internally at
Symbolics for a year or so, but have not had the resources to qualify
them for release to customers. They can be quite efficient, and of
course can significantly improve the efficiency of some kinds of
programs.
But perhaps this isn't exactly the right question for such a late date
in the CL standards process. Rather:
Can such tables be implemented with reasonable performance
in *all* existing CL implementations, without breaking the GC
strategies upon which they depend?
I myself have no idea which way this question would fall, but unless
it could confidently be answered in the affirmative I feel X3J13 would
have to exclude these `weak-pointer' tables from the standard. The
*real* problem is that it would be incumbent on the *proposer* to
prove practicality. This would not be an easy proof.
Well, we haven't done it for standard architectures, but it would seem
to be straightforward to add the feature to any copying garbage
collector. Simplisticly, all you have to do is modify the scavenger to
make two passes: The first pass skips any references from weak tables,
and the second pass replaces oldspace references to the deleted objects
with a null marker. The overhead of the second pass can typically be
minimized by always creating such tables in a special part of address
space, so the second pass has little overhead. There are many other
possible optimizations.
My point is, it has nothing to do with hardware support; it's at the
next higher level. Hardware support at best will just give you a better
scavenger to build this on.
∂31-Aug-88 1849 Common-Lisp-mailer Re: hash tables and GC
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 31 Aug 88 18:49:35 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 31 Aug 88 21:43:52 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 31 Aug 88 21:47:33 EDT
Date: Wed, 31 Aug 88 21:47 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: hash tables and GC
To: David L. Andre <DLA@jasper.scrc.symbolics.com>
Cc: smh@ems.media.mit.edu, common-lisp@sail.stanford.edu
In-Reply-To: <19880901010347.3.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Message-Id: <19880901014745.2.BARMAR@OCCAM.THINK.COM>
Date: Wed, 31 Aug 88 21:03 EDT
From: David L. Andre <DLA@jasper.scrc.symbolics.com>
Well, we haven't done it for standard architectures, but it would seem
to be straightforward to add the feature to any copying garbage
collector. Simplisticly, all you have to do is modify the scavenger to
make two passes: The first pass skips any references from weak tables,
and the second pass replaces oldspace references to the deleted objects
with a null marker. The overhead of the second pass can typically be
minimized by always creating such tables in a special part of address
space, so the second pass has little overhead. There are many other
possible optimizations.
My point is, it has nothing to do with hardware support; it's at the
next higher level. Hardware support at best will just give you a better
scavenger to build this on.
There's actually an even more trivial solution: don't implement them if
you don't want to!
The difference between weak tables and ordinary tables is that the
implementation is ALLOWED to GC entries in weak tables. However, just
as Common Lisp never actually says that an implementation MUST have a
GC, it can't REQUIRE an implementation to GC entries in a weak table.
So, if your GC is not easily extended to support weak tables, you can
simply ignore the :WEAK (or whatever) option. The only invalid way to
implement weak tables is to implement them in such a way that they GC
entries that they shouldn't; remembering too much should never bother a
valid CL program (unless it runs out of memory, but that's outside the
language spec). (Hmm, this argument would justify a Lisp implementation
that used only a reference-count GC, but I expect that there would be
far fewer weak tables than circular structures, so the argument doesn't
really scale up.)
By the way, I assume that David meant that only key fields of tables
should be skipped. Otherwise you could end up with keys whose values
have been GCed.
By the way, here is how I think weak tables could be implemented in a
mark-sweep GC (are there any of those around any more?):
During the mark phase, don't recurse through the keys of any weak
tables. Before the sweep phase, make another pass, deleting any weak
table entries whose keys are not marked.
The added passes of both the copying and mark/sweep GCs would be sped up
significantly if the implementation maintained a list of all weak tables
(or it could cons up such a list during the first pass), so that it
wouldn't have to make a full pass through memory to find them.
barmar
∂31-Aug-88 1950 Common-Lisp-mailer Re: hash tables and GC
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 31 Aug 88 19:50:40 PDT
Received: from KOYAANISQATSI.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 213821; Wed 31-Aug-88 22:49:45 EDT
Date: Wed, 31 Aug 88 22:49 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: hash tables and GC
To: barmar@Think.COM
cc: smh@ems.media.mit.edu, common-lisp@sail.stanford.edu
In-Reply-To: <19880901014745.2.BARMAR@OCCAM.THINK.COM>
Message-ID: <19880901024922.3.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Date: Wed, 31 Aug 88 21:47 EDT
From: Barry Margolin <barmar@Think.COM>
There's actually an even more trivial solution: don't implement them if
you don't want to!
Of course.
The difference between weak tables and ordinary tables is that the
implementation is ALLOWED to GC entries in weak tables. However, just
as Common Lisp never actually says that an implementation MUST have a
GC, it can't REQUIRE an implementation to GC entries in a weak table.
So, if your GC is not easily extended to support weak tables, you can
simply ignore the :WEAK (or whatever) option. The only invalid way to
implement weak tables is to implement them in such a way that they GC
entries that they shouldn't; remembering too much should never bother a
valid CL program (unless it runs out of memory, but that's outside the
language spec). (Hmm, this argument would justify a Lisp implementation
that used only a reference-count GC, but I expect that there would be
far fewer weak tables than circular structures, so the argument doesn't
really scale up.)
By the way, I assume that David meant that only key fields of tables
should be skipped. Otherwise you could end up with keys whose values
have been GCed.
I can think of applications for weak-key, weak-value, and
weak-key-and-value hash tables. Certainly weak-key is the most
generally useful.
By the way, here is how I think weak tables could be implemented in a
mark-sweep GC (are there any of those around any more?):
During the mark phase, don't recurse through the keys of any weak
tables. Before the sweep phase, make another pass, deleting any weak
table entries whose keys are not marked.
The added passes of both the copying and mark/sweep GCs would be sped up
significantly if the implementation maintained a list of all weak tables
(or it could cons up such a list during the first pass), so that it
wouldn't have to make a full pass through memory to find them.
Sounds reasonable given 10 seconds of thought.
∂01-Sep-88 0830 Common-Lisp-mailer Re: hash tables and GC
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 1 Sep 88 08:30:23 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA00519; Thu, 1 Sep 88 09:29:10 MDT
Date: Thu, 1 Sep 88 09:29:10 MDT
From: sandra@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8809011529.AA00519@cs.utah.edu>
Subject: Re: hash tables and GC
Newsgroups: fa.common-lisp
To: common-lisp@sail.stanford.edu
I suppose I should throw in my $.02 worth on this issue. A couple of
weeks ago I was hacking on a piece of code where I thought that my job
would be made much easier if I could attach some extra information to
arbitrary objects. Specifically, I was thinking it would be nice to be
able to attach a property list to arbitrary objects, and not just to
symbols. (Two objects that are EQ would have the same property list.)
As far as what it would allow you to do, this functionality is actually
pretty close to what is being proposed with the GC'able hash tables, and
I think it has some advantages. First, it would allow more freedom of
implementation; off the top of my head, I can think of at least two
approaches to doing it. And, it avoids some of the strangenesses that
would result from forcing GC'able hash tables into the same mold as
ordinary hash tables (like not allowing EQUAL as the :TEST, and MAPHASH
finding different sets of objects in the hash table depending on when
the last GC was).
Anybody else think this is worth pursuing?
-Sandra
∂01-Sep-88 0924 Common-Lisp-mailer Re: hash tables and GC
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 1 Sep 88 09:24:53 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA01353; Thu, 1 Sep 88 09:21:50 PDT
Received: from clam.sun.com by snail.sun.com (4.0/SMI-4.0)
id AA19954; Thu, 1 Sep 88 09:24:39 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA13220; Thu, 1 Sep 88 09:25:04 PDT
Date: Thu, 1 Sep 88 09:25:04 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8809011625.AA13220@clam.sun.com>
To: common-lisp@sail.stanford.edu, sandra@cs.utah.edu
Subject: Re: hash tables and GC
I've wished for the ability to put properties on arbitrary objects
via hash tables without making the objects with properties non-collectable.
I've written code that maps values such as strings to objects
(a lot like a package does!). The purpose was for all
equivalent values to map to a single object, so that any value in
an equivalence class could share a set of properties with its
equivalent values. I have wished that this mapping would not permanently
hold onto the *objects*. If the object has no properties and no
references except through the table it could be reclaimed.
On the other hand, I'm not sure these are the most pressing issues
around.
-Cris
∂01-Sep-88 1210 Common-Lisp-mailer Re: hash tables and GC
Received: from FRED.SLISP.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 1 Sep 88 12:09:51 PDT
Received: from FRED.SLISP.CS.CMU.EDU by FRED.SLISP.CS.CMU.EDU; 1 Sep 88 15:08:02 EDT
To: sandra@cs.utah.edu (Sandra J Loosemore)
cc: common-lisp@sail.stanford.edu
Subject: Re: hash tables and GC
In-reply-to: Your message of Thu, 01 Sep 88 09:29:10 -0600.
<8809011529.AA00519@cs.utah.edu>
Date: Thu, 01 Sep 88 15:07:46 EDT
From: Rob.MacLachlan@WB1.CS.CMU.EDU
There is also the rather similar "weak pointer" notion, which I believe is
implemented in T. The operations on a weak pointer are something like:
MAKE-WEAK-POINTER Object => Weak-Pointer
INDIRECT-WEAK-POINTER Weak-Pointer => Object or NIL
Having a weak pointer to an object allows you to keep track of it, but
doesn't prevent GC. Although I haven't ever used either weak pointers or
GC'able hash-tables, I think weak pointers are superior as a language
feature, since they are more primitive and potentially more efficient.
The GC-able hash-table notion unnecessarily complicates the semantics by
rolling in hash-table semantics when the real issue is with GC. Usually
the association capacity of hashtables is unnecessary: instead of
weak-hashing from A to B, allocate another slot in A to hold the weak
pointer to B.
The implementation issues are basically the same as for GC-able
hash-tables, but weak pointers seem to have a sight edge. They can be
implemented by allocating weak pointers in a special area, but given
abundant tag bits, immediate representations are also conceivable.
Rob
∂01-Sep-88 2339 Common-Lisp-mailer hash tables and GC
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 1 Sep 88 23:39:19 PDT
Received: from bhopal ([192.9.200.13]) by heavens-gate id AA05817g; Thu, 1 Sep 88 22:36:48 PST
Received: by bhopal id AA04580g; Thu, 1 Sep 88 23:36:06 PDT
Date: Thu, 1 Sep 88 23:36:06 PDT
From: Jon L White <jonl@lucid.com>
Message-Id: <8809020636.AA04580@bhopal>
To: barmar@Think.COM
Cc: DLA@jasper.scrc.symbolics.com, smh@ems.media.mit.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Barry Margolin's message of Wed, 31 Aug 88 21:47 EDT <19880901014745.2.BARMAR@OCCAM.THINK.COM>
Subject: hash tables and GC
re: By the way, here is how I think weak tables could be implemented in a
mark-sweep GC (are there any of those around any more?):
During the mark phase, don't recurse through the keys of any weak
tables. Before the sweep phase, make another pass, deleting any weak
table entries whose keys are not marked.
In fact, PDP10 MacLisp's OBARRAY (the hash-table for interned symbols)
was implemented in the obvious way so that "truly worthless atoms"
could be garbage collected, even though they were entered in the table.
[There was a mode switch -- (SSTATUS GCTWA t-or-nil) -- to turn this
capability on or off, since it did cost a marginal amount more of time].
The explicit step that is needed but not directly mentioned in your wording
of the algorithm is that "value" links must be recursed through during the
mark phase (for MacLisp, this meant descending the value-cell and plist
attributes of interned symbols, without marking the symbol itself). That
is, value links for entries that will not be deleted *may* contain the only
pointers to other keys which protect those keys from undesired removal.
In many reference counting garbage collectors, it is possible to ask "Is
the reference count of this object equal to 1?" [and in the Deutsch/Bobrow
variations, you can at least ask this question at scavenge time, even though
you may not be able to ask it an just any old time]. If the answer to this
question is Yes for a key in a "weak" table, then it must be that the one
pointer to it is the table entry itself; hence it may be deleted.
In VAX/NIL, we had devised a scheme for a sort of "weak pointer" table
even though the garbage collector was to be a copying one. [It was
mostly in conjunction with an emulation of the MAKNUM function of PDP10
MacLisp, which didn't do copying.] But alas, as the GC was last on the
implementation agenda . . . well, suffice it to say that we didn't ever
find out what the performance implication of that scheme would be.
-- JonL --
∂03-Sep-88 1147 Common-Lisp-mailer Re: hash tables and GC
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 Sep 88 11:47:35 PDT
Received: from Burger.ms by ArpaGateway.ms ; 03 SEP 88 11:46:29 PDT
Sender: "Larry_Masinter.PARC"@Xerox.COM
Date: 3 Sep 88 11:46:07 PDT (Saturday)
Subject: Re: hash tables and GC
From: "Larry_Masinter.PARC"@Xerox.COM
To: common-lisp@sail.stanford.EDU
In-Reply-to: smh's message of 29 Aug 88 23:07
Message-ID: <880903-114629-8359@Xerox>
I recall that in the early-70s, Interlisp-10 only had EQ hash tables and would
GC hash keys if the hash table was the only pointer. However, Peter Deutsch had
an application (a theorem prover, I think) which used hash tables as the only
pointers to his data structures and then used MAPHASH to retrieve them. So we
changed the GC not to collect hash keys; I'm not sure when, but I'd guess around
1975. We thought about having both kinds of hash tables, but didn't implement
it.
My point is that the proposal isn't a novel feature (or issue) for Lisp
implementations.
It would be most useful to describe the proposal in terms of the semantics from
the point of view of Lisp programs rather than the implementation of the garbage
collector, especially since CLtL and the spec make almost no reference to the GC
at all. The only semantic difference between :TEMPORARY and non-:TEMPORARY hash
tables is that MAPHASH on :TEMPORARY hash tables may find fewer entries.
For me, the questions remaining are:
0. Is :TEMPORARY T a good indicator? The table isn't really temporary, just the
entires. Perhaps :MAPHASH T or :MAPHASH NIL?
1. How to describe the behavior of MAPHASH on such a table; are the results
"undefined"?
Didn't we already have this discussion on the Common-Lisp mailing list a while
ago? Or was it about DO-ALL-SYMBOLS and packages...?
∂04-Sep-88 1229 Common-Lisp-mailer Re: hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 4 Sep 88 12:28:34 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04316; 4 Sep 88 19:45 BST
Date: Sun, 4 Sep 88 20:12:49 BST
Message-Id: <13499.8809041912@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: hash tables and GC
To: Sandra J Loosemore <sandra@cs.utah.edu>, sandra@cs.utah.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Sandra J Loosemore's message of Thu, 1 Sep 88 09:29:10 MDT
> Specifically, I was thinking it would be nice to be
> able to attach a property list to arbitrary objects, and not just to
> symbols. (Two objects that are EQ would have the same property list.)
>
> As far as what it would allow you to do, this functionality is actually
> pretty close to what is being proposed with the GC'able hash tables, and
> I think it has some advantages. First, it would allow more freedom of
> implementation; off the top of my head, I can think of at least two
> approaches to doing it. And, it avoids some of the strangenesses that
> would result from forcing GC'able hash tables into the same mold as
> ordinary hash tables (like not allowing EQUAL as the :TEST, and MAPHASH
> finding different sets of objects in the hash table depending on when
> the last GC was).
As you may recall, my original message took the idea from "temporary
properties" in Pop11. So, the notion of "property" is OK with me. But,
I'm not so happy with property *list*, which implies (1) linear search,
(2) the existence of an actual list, and (3) a format for the list (an
alternating sequence of property names and property values).
-- Jeff
∂04-Sep-88 1319 Common-Lisp-mailer Re: hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 4 Sep 88 13:17:25 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04434; 4 Sep 88 20:43 BST
Date: Sun, 4 Sep 88 21:10:24 BST
Message-Id: <13560.8809042010@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: hash tables and GC
To: Rob.MacLachlan@wb1.cs.cmu.edu, Sandra J Loosemore <sandra@cs.utah.edu>
In-Reply-To: Rob.MacLachlan@edu.cmu.cs.wb1's message of Thu, 01 Sep 88 15:07:46 EDT
Cc: common-lisp@sail.stanford.edu
> There is also the rather similar "weak pointer" notion, which I believe is
> implemented in T.
Yes, T does have weak pointers. They were also in RnRS for some n (as
object-hash and object-unhash).
I had thought that weak pointers might be sufficient, but then could
not see any nice way to use them to implement what I really wanted.
> The GC-able hash-table notion unnecessarily complicates the semantics by
> rolling in hash-table semantics when the real issue is with GC.
You're right, to some extent. But hash tables are the way Common Lisp
provides efficient table-like mappings from keys to values. You might
use something like a-lists instead, but only if a linear search is
fast enough. You might implement a new facility of your own, but only
if you wanted it to be significantly different from hash tables.
My feeling is that a new kind of table-like mapping from keys to
values that didn't prevent keys from being collected would be so much
like hash tables that they might as well be hash tables.
Or, we could look at it the other way around. A hash table is a
mapping from keys to values. Why should a key be uncollectable just
because it was given a value in a mapping? When the key is no longer
referenced (except in the mapping), why must it's entry remain? Well,
in some cases you may want it to remain, but I suspect that those
cases are actually in the minority.
Perhaps a better proposal would be to change hash tables to always
have all entries be "temporary". But then we have a problem with
backwards compatibility.
> Usually the association capacity of hashtables is unnecessary: instead
> of weak-hashing from A to B, allocate another slot in A to hold the weak
> pointer to B.
Weak pointers are more general. You can put them in lists, etc., not
just in hash tables. But: (1) What if you can't add a slot to A? (2)
What if only a small number of objects of the same type as A need the
slot? (3) What if what you need is a weak pointer to A, not to B?
That is what I actually want form the tables. I want the keys to be
collectable. (But, since a hash table is a mapping from keys to
values, values will be collectable when no longer needed for may key.)
To implement tables with weak pointers to the keys, you need access to
an EQ hash function and you need it to be an efficient hash that works
even when objects might be moved. I suspect that would be very
difficult. By having the tables built in, you do not need to provide
the hash function.
Then, once you have the tables, you can easily implement weak pointers
and put them in lists, etc.
-- Jeff
∂06-Sep-88 1808 Common-Lisp-mailer Hash Tables and GC
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 6 Sep 88 18:08:07 PDT
Posted-Date: Tue, 06 Sep 88 17:08:03 PST
Message-Id: <8809070108.AA13965@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA13965; Tue, 6 Sep 88 18:08:06 PDT
To: COMMON-LISP@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: Hash Tables and GC
Cc: jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
Date: Tue, 06 Sep 88 17:08:03 PST
Sender: goldman@vaxa.isi.edu
Add a keyword parameter :TEMPORARY to MAKE-HASH-TABLE. If this
argument is specified and not NIL, and if :TEST is #'EQ or #'EQL,
entries in the table may be removed by the GC if the key (i.e.,
an object EQ or EQL to the key) IS ACCESSIBLE ONLY THROUGH THE
TABLE. Entries in EQUAL tables are never so removed, nor are
numbers in EQL tables. [Explanation: in these cases, it is
generally possible to construct new objects that are respectively
EQUAL or EQL to the key.]
Numbers and Characters could never be removed from EQL tables, because
they ARE always accessible in other ways. But what is the rationale for
PROHIBITING the removal of an entry from an EQUAL hash table if its
key is in fact accessible ONLY through the table? E.g., defstruct
instances and symbols can be legitimately used as keys in an EQUAL hash
table, so an implementation that removed them from EQ hash tables
would be able to remove them from EQUAL tables as well. Note that
all discussions of this topic have considered an implementation correct
even if it NEVER removed entries, and I don't recall anyone implying
that an implementation that did remove entries was required to remove
ALL removable entries.
Also, the think the proposal should explicitly state that
IT IS AN ERROR to apply MAPHASH or HASH-TABLE-COUNT to
a TEMPORARY hash table. (Alternatively, the proposal could state what
useful behavior can be relied on for these functions with
temporary hash tables. For instance, they could map over / count all
the non-garbage entries as well as whatever gargage entries had
not yet been collected. But would that be useful?)
Neil
∂06-Sep-88 1953 Common-Lisp-mailer Re: Hash Tables and GC
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 6 Sep 88 19:53:04 PDT
Received: from Semillon.ms by ArpaGateway.ms ; 06 SEP 88 19:51:12 PDT
Date: Tue, 6 Sep 88 19:50 PDT
From: Gregor.pa@Xerox.COM
Subject: Re: Hash Tables and GC
To: goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
Fcc: BD:>Gregor>mail>outgoing-mail-4.text.newest
In-Reply-To: <8809070108.AA13965@vaxa.isi.edu>
Message-ID: <19880907025057.5.GREGOR@PORTNOY.parc.xerox.com>
Line-fold: no
As I understand it, finalization is a mechanism for recording a function
which the garbage collector should call on an object when it is about to
be GC'd.
I find it surprising that no one has talked about finalization during
this discussion. This may not be facility we want to add to Common
Lisp, but as near as I can tell, weak pointers and finalization are the
primitives you need to build these kind of hash tables.
In addition, finalization is a useful mechanism to have direct access
to.
-------
∂07-Sep-88 0515 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 7 Sep 88 05:15:09 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa06150; 7 Sep 88 8:14 EDT
Received: from draper.com by RELAY.CS.NET id ab13145; 7 Sep 88 7:59 EDT
Date: Wed, 7 Sep 88 07:52 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Implementing :TEMPORARY hash tables at the Lisp level?
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.edu",SEB1525
Just a question. If one were to implement :TEMPORARY hash tables as
described - i.e. testing to see if the test were #'EQ or #'EQL - well,
just how does one code such a test in CL? Presumably you'd have code like
(case test
((#'eq #'eql) (make-em-collectible))
((#'equal) (dont-make-em-collectible))
(otherwise (make-em-whatever-you-want)))
But... there is no way of testing equality of functions, lexical closures,
or what have you, in CL. So how can this possibly be implemented?
∂07-Sep-88 0913 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 7 Sep 88 09:13:07 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 7 Sep 88 12:13:56 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 7 Sep 88 12:11:01 EDT
Date: Wed, 7 Sep 88 12:07 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Implementing :TEMPORARY hash tables at the Lisp level?
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8809071217.AA06853@Think.COM>
Message-Id: <19880907160730.3.BARMAR@OCCAM.THINK.COM>
Date: Wed, 7 Sep 88 07:52 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Just a question. If one were to implement :TEMPORARY hash tables as
described - i.e. testing to see if the test were #'EQ or #'EQL - well,
just how does one code such a test in CL? Presumably you'd have code like
(case test
((#'eq #'eql) (make-em-collectible))
((#'equal) (dont-make-em-collectible))
(otherwise (make-em-whatever-you-want)))
But... there is no way of testing equality of functions, lexical closures,
or what have you, in CL. So how can this possibly be implemented?
The internal implementation of a Common Lisp need not be written using
portable constructs.
I suspect that in most CL implementations, #'<symbol> always returns the
same thing for symbols that do not have a lexical function binding, so
the above code would work. If not, then the hash table implementation
will have to use some implementation-dependent functions to extract the
function object from a closure and compare it against the function
bindings of EQ, EQL, and EQUAL.
In fact, current implementations of MAKE-HASH-TABLE must already have
something like this, since the hash function of a hash table must be
dependent on the :TEST argument.
barmar
∂07-Sep-88 1012 Common-Lisp-mailer Re: Hash Tables and GC
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Sep 88 10:12:48 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 455541; Wed 7-Sep-88 13:08:22 EDT
Date: Wed, 7 Sep 88 13:07 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Hash Tables and GC
To: Gregor.pa@Xerox.COM, goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: <19880907025057.5.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880907170749.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Tue, 6 Sep 88 19:50 PDT
From: Gregor.pa@Xerox.COM
As I understand it, finalization is a mechanism for recording a function
which the garbage collector should call on an object when it is about to
be GC'd.
I find it surprising that no one has talked about finalization during
this discussion.
I guess my previous mail did not get through. I'll recap. We had an
uninstalled version of finalization (not the name we used, but
"finalization" is better) and weak pointers in the SWIFT system. SWIFT
wasn't written in LISP, but it is still applicable (CLU is another GC'd
language, which you can consider sort of Lisp with syntax, strong
typing, and compile time type checking, for the purpose of this
conversation).
There are only two points about finalization that I feel should be
brought up. First, we found it useful to allow the finalization funarg
to return a value indicating whether or not to *really* GC the object.
The finalization funarg was called on every GC pass when the only
pointers to an object were weak pointers. If it returned FALSE, then
the object survived the GC, TRUE then the storage was reclaimed.
Second, given a finalization funarg, it is possible to lie to the GC
(keep, or create, another reference to the object). Therefore, the GC
reclaimed weak-pointer objects by clearing the pointer to the object in
the weak pointer, so that if there *really* are no other references to
the object it would be reclaimed on the next pass.
We had a non-compacting, mark and sweep, parallel ("real time") GC, FYI,
since someone asked about this before.
This may not be facility we want to add to Common
Lisp, but as near as I can tell, weak pointers and finalization are the
primitives you need to build these kind of hash tables.
In addition, finalization is a useful mechanism to have direct access
to.
Yes. It's not just useful in hash tables, and it allows multiple
weak-pointers to the same object. It was mainly useful for unlinking
and caching. (SWIFT ran in a single address space, so if you wanted to
flush some application completely from the world, you had to make sure
that you didn't leave a pointer to some data structure squirreled away
somewhere in the bowels of the operating system. Weak pointers (it was
actually more like "weak objects" (or "GCable objects")) solved this
problem.) In a lisp application where each process gets its own address
space that is killed when the process is killed, I'm not sure if there
is an advantage in having multiple weak-pointers to the same object, but
still, weak-pointers and finalization provide a lot more flexibility
than simply implementing temporary hash tables.
∂07-Sep-88 1055 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 7 Sep 88 10:52:55 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06322; 7 Sep 88 17:57 BST
Date: Wed, 7 Sep 88 18:26:30 BST
Message-Id: <21061.8809071726@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Implementing :TEMPORARY hash tables at the Lisp level?
To: "Steve Bacher (Batchman)" <SEB1525%draper.com@NSS.Cs.Ucl.AC.UK>,
SEB1525%draper.com@NSS.Cs.Ucl.AC.UK, common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Wed, 7 Sep 88 07:52 EDT
> Just a question. If one were to implement :TEMPORARY hash tables as
> described - i.e. testing to see if the test were #'EQ or #'EQL - well,
> just how does one code such a test in CL? Presumably you'd have code like
>
> (case test
> ((#'eq #'eql) (make-em-collectible))
> ((#'equal) (dont-make-em-collectible))
> (otherwise (make-em-whatever-you-want)))
>
> But... there is no way of testing equality of functions, lexical closures,
> or what have you, in CL. So how can this possibly be implemented?
This problem already exists for hash tables: something must see whether
the :TEST argument is EQ, EQL, or EQUAL. I suspect this involves code
like the following:
(cond ((or (eq test #'eq) (eq test 'eq))
...eq hash table...)
((or (eq test #'eql) (eq test 'eql))
...eql hash table...)
((eq (eq test #'equal) (eq test 'equal))
...equal hash table...)
(t ...whatever...))
Functions can be compared with EQ, EQL, and EQUAL, but the meaning is
not "do they compute the same (mathematical) function". Code like
the following will not work:
(make-hash-table :test #'(lambda (a b) (eq a b)))
-- Jeff
∂07-Sep-88 1125 Common-Lisp-mailer Re: Hash Tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 7 Sep 88 11:24:16 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06508; 7 Sep 88 18:31 BST
Date: Wed, 7 Sep 88 19:00:12 BST
Message-Id: <21247.8809071800@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Hash Tables and GC
To: COMMON-LISP@sail.stanford.edu, goldman@vaxa.isi.edu
Cc: jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>
> Add a keyword parameter :TEMPORARY to MAKE-HASH-TABLE. If this
> argument is specified and not NIL, and if :TEST is #'EQ or #'EQL,
> entries in the table may be removed by the GC if the key (i.e.,
> an object EQ or EQL to the key) IS ACCESSIBLE ONLY THROUGH THE
> TABLE. Entries in EQUAL tables are never so removed, nor are
> numbers in EQL tables. [Explanation: in these cases, it is
> generally possible to construct new objects that are respectively
> EQUAL or EQL to the key.]
>
> Numbers and Characters could never be removed from EQL tables, because
> they ARE always accessible in other ways. But what is the rationale for
> PROHIBITING the removal of an entry from an EQUAL hash table if its
> key is in fact accessible ONLY through the table? E.g., defstruct
> instances and symbols can be legitimately used as keys in an EQUAL hash
> table, so an implementation that removed them from EQ hash tables
> would be able to remove them from EQUAL tables as well.
You are quite correct; I neglected to include characters with numbers
as objects that could not be removed from EQL tables and also to
consider the cases where EQUAL was equivalent to EQL (for EQUAL hash
tables). The latter point is important because it makes EQUAL tables
less of a special case. Thank you for bringing it up.
> Note that
> all discussions of this topic have considered an implementation correct
> even if it NEVER removed entries, and I don't recall anyone implying
> that an implementation that did remove entries was required to remove
> ALL removable entries.
I agree. Moreover, there will be times when removable entries have
not yet been removed even if they will be removed eventually.
Or, consider lists in EQUAL tables. I would not expect list-key
entries to be removed even though some might be removable in principle
when they contain EQ-unique objects accessable only through the table
entry.
-- Jeff
∂07-Sep-88 1130 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 7 Sep 88 11:30:28 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 7 Sep 88 14:31:10 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 7 Sep 88 14:28:01 EDT
Date: Wed, 7 Sep 88 14:24 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: Implementing :TEMPORARY hash tables at the Lisp level?
To: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Cc: "Steve Bacher (Batchman)" <SEB1525%draper.com@NSS.Cs.Ucl.AC.UK>,
SEB1525%draper.com@NSS.Cs.Ucl.AC.UK, common-lisp@sail.stanford.edu
In-Reply-To: <21061.8809071726@subnode.aiai.ed.ac.uk>
Message-Id: <19880907182427.4.BARMAR@OCCAM.THINK.COM>
Date: Wed, 7 Sep 88 18:26:30 BST
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Functions can be compared with EQ, EQL, and EQUAL,
Function objects can, but not the results of invocations of the FUNCTION
special form. On p.89, CLtL says, "a perfectly valid implementation
might simply cause every distinct evaluation of a FUNCTION form to
produce a new closure object not EQ to any other." The precise behavior
of the FUNCTION special form in this regard will frequently depend on
whether the code is compiled or interpreted and whether the argument is
a global function name, a local function name, or a lambda expression.
For example, in Symbolics Common Lisp the function
(defun fn-eq-test (a)
(flet ((internal () (cons a a)))
(eq #'internal #'internal)))
returns NIL when interpreted, but T when compiled. The interpreter
definition of FUNCTION simply makes a new lexical closure, while the
compiler collapses equivalent lexical closures.
barmar
∂07-Sep-88 1159 Common-Lisp-mailer Re: Hash Tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 7 Sep 88 11:56:53 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06905; 7 Sep 88 19:20 BST
Date: Wed, 7 Sep 88 19:49:10 BST
Message-Id: <21507.8809071849@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Hash Tables and GC
To: COMMON-LISP@sail.stanford.edu, goldman@vaxa.isi.edu
Cc: jeff <@NSS.Cs.Ucl.AC.UK:jeff@aiai.edinburgh.ac.uk>
> Also, the think the proposal should explicitly state that
> IT IS AN ERROR to apply MAPHASH or HASH-TABLE-COUNT to
> a TEMPORARY hash table. (Alternatively, the proposal could state what
> useful behavior can be relied on for these functions with
> temporary hash tables. For instance, they could map over / count all
> the non-garbage entries as well as whatever garbage entries had
> not yet been collected. But would that be useful?)
This question is tied to that of whether temporary tables should be a
variety of hash table or a tables of a new type. If they are hash
tables, I think it should be possible to apply MAPHASH and HASH-TABLE-
COUNT (with the understanding that some entries might vanish without
an explicit REMHASH). It would be too great an inconsistency to
disallow these operations.
Moreover, if we feel the operations *are* useful, that would be an
additional reason to make temporary tables be hash tables. (This is
the "they would be so like hash tables that they might as well *be*
hash tables" argument.)
However, suppose temporary tables are not hash tables. Then we might
omit operations like MAPHASH and HASH-TABLE-COUNT, for simplicity, but
also because removability would then follow automatically: there would
be no way to determine that *any* entries had been removed unless there
was some independent reference to the keys, and so entries without such
an independent reference could be removed. There would be no need to
mention garbage collection in the description of the tables.
[BTW, this suggests that the keyword argument to MAKE-HASH-TABLE might
be :MAPPABLE rather than :TEMPORARY. Tables that were not mappable
could have entries secretly removed. Of course, another choice would
be to have :PERMANENT, defaulting to T, instead of :TEMPORARY,
defaulting to NIL.]
The reason I have not advocated this approach is that I suspect that
mapping over temporary tables is useful. For example, a table where
the values are meant only to be "true" would be a "weak set", presence
in the table indicating membership in the set. It makes sense to ask
what objects are (still) in the set.
Moreover, implementation of such tables tend to provide mapping
operations. T, which has weak sets but not the general tables,
provides a WALK-WEAK-SET to map over the set as well as WEAK-SET->LIST
to give a list of the members. Pop11, which has tables with temporary
entries, also provides a mapping operation.
-- Jeff
∂07-Sep-88 1222 Common-Lisp-mailer Re: Hash Tables and GC
Received: from WHITE.SWW.Symbolics.COM ([128.81.57.24]) by SAIL.Stanford.EDU with TCP; 7 Sep 88 12:22:44 PDT
Received: from PURPLE.SWW.Symbolics.COM by WHITE.SWW.Symbolics.COM via CHAOS with CHAOS-MAIL id 206707; Wed 7-Sep-88 11:51:58 PDT
Date: Wed, 7 Sep 88 11:52 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Subject: Re: Hash Tables and GC
To: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>, Gregor.pa@Xerox.COM,
goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
Fcc: W:>ddyer>mail.sent.newest
In-Reply-To: <19880907170749.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Message-ID: <19880907185230.5.DDYER@PURPLE.SWW.Symbolics.COM>
Just to throw a little light into this discussion: On Symbolics systems there
is a list of forms to be evaluated before any gc flip (ephemeral or dynamic).
It's possible to implement whatever kind of weak pointers strategy you want by
explicitly clearing whatever pointers are "weak" before the flip occurs. The
list is called SI:GC-EVERY-FLIP-LIST
∂07-Sep-88 1252 Common-Lisp-mailer Re: Hash Tables and GC
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Sep 88 12:52:47 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 455709; Wed 7-Sep-88 15:50:05 EDT
Date: Wed, 7 Sep 88 15:49 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Hash Tables and GC
To: DDYER@RIVERSIDE.SCRC.Symbolics.COM, Greenwald@STONY-BROOK.SCRC.Symbolics.COM,
Gregor.pa@Xerox.COM, goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: <19880907185230.5.DDYER@PURPLE.SWW.Symbolics.COM>
Message-ID: <19880907194934.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Wed, 7 Sep 88 11:52 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Just to throw a little light into this discussion: On Symbolics systems there
is a list of forms to be evaluated before any gc flip (ephemeral or dynamic).
It's possible to implement whatever kind of weak pointers strategy you want by
explicitly clearing whatever pointers are "weak" before the flip occurs. The
list is called SI:GC-EVERY-FLIP-LIST
How does this tell you whether there *are* any non-weak pointers to the
object in question?
∂07-Sep-88 1254 Common-Lisp-mailer Re: Hash Tables and GC
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 7 Sep 88 12:54:30 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 7 Sep 88 15:54:21 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 7 Sep 88 15:51:30 EDT
Date: Wed, 7 Sep 88 15:47 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: Re: Hash Tables and GC
To: DDYER@riverside.scrc.symbolics.com
Cc: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>,
Gregor.pa@xerox.com, goldman@vaxa.isi.edu,
COMMON-LISP@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: <19880907185230.5.DDYER@PURPLE.SWW.Symbolics.COM>
Message-Id: <19880907194758.9.BARMAR@OCCAM.THINK.COM>
Date: Wed, 7 Sep 88 11:52 PDT
From: DDYER@riverside.scrc.symbolics.com
Just to throw a little light into this discussion: On Symbolics systems there
is a list of forms to be evaluated before any gc flip (ephemeral or dynamic).
It's possible to implement whatever kind of weak pointers strategy you want by
explicitly clearing whatever pointers are "weak" before the flip occurs. The
list is called SI:GC-EVERY-FLIP-LIST
I don't think this works. After the flip finishes you will then need to
restore the weak pointers that pointed to objects that also had strong
pointers pointing to them. How do you do this?
barmar
∂07-Sep-88 1305 Common-Lisp-mailer Re: Hash Tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 7 Sep 88 13:02:10 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07379; 7 Sep 88 20:23 BST
Date: Wed, 7 Sep 88 20:51:39 BST
Message-Id: <21582.8809071951@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Hash Tables and GC
To: Michael Greenwald <Greenwald@scrc-stony-brook.arpa>, Gregor.pa@xerox.com,
goldman@vaxa.isi.edu
In-Reply-To: Michael Greenwald's message of Wed, 7 Sep 88 13:07 EDT
Cc: COMMON-LISP@sail.stanford.edu
> Date: Tue, 6 Sep 88 19:50 PDT
> From: Gregor.pa@Xerox.COM
>
> This may not be facility we want to add to Common
> Lisp, but as near as I can tell, weak pointers and finalization are the
> primitives you need to build these kind of hash tables.
>
> In addition, finalization is a useful mechanism to have direct access
> to.
>
> Yes. It's not just useful in hash tables, and it allows multiple
> weak-pointers to the same object. [...] I'm not sure if there is an
> advantage in having multiple weak-pointers to the same object, but
> still, weak-pointers and finalization provide a lot more flexibility
> than simply implementing temporary hash tables.
Can weak pointers can be implemented using temp-entry tables? I think
something like the following might work:
(let ((table (make-hash-table :test #'eq :temporary t))
(inverse (make-hash-table :test #'eq :temporary t)))
(defun make-weak-pointer (object)
(let ((wp (gethash object table nil)))
(when (null wp)
(setq wp (list "weak pointer"))
(setf (gethash object table) wp)
(setf (gethash wp inverse) object))
wp))
(defun deref (wp)
(gethash wp inverse nil))
)
Unfortunately, these weak pointers can't be collected while there are still
references to the corresponding objects. This suggests that we may want
tables from which entries can be removed when there is no other reference
to the value [or the key?]. Then, if there were no reference to the weak
pointer, the entries in both TABLE and INVERSE could be removed. Or we
could have tables that hashed both ways.
Oh, well. Perhaps we *should* look to lower-level primitives. The reasons
against that approach, though, seem to be the following:
(1) Weak tables are as good as weak pointers for many purposes.
(2) Weak tables are sufficiently useful in their own right that they
should be provided even if lower-level primitives are also available.
(3) Weak pointers + finalization are insufficient for implementing weak
tables because one also needs EQ-hashing that is efficient and yet
doesn't break when used with a GC that moves objects. [I would be
pleased to find that I am wrong on this point.]
[OK, maybe something like this:
(defun make-weak-table () (make-hash-table))
(defun weak-gethash (object table)
(gethash (unique-weak-pointer object) table))
But when the weak pointer becomes invalid, the table entry
must still remain. Enter finalization?]
(4) While it seems possible that weak tables might be accepted as as
addition to Common Lisp, it seems less likely that finalization
would be.
-- Jeff
∂07-Sep-88 1306 Common-Lisp-mailer Re: Hash Tables and GC
Received: from WHITE.SWW.Symbolics.COM ([128.81.57.24]) by SAIL.Stanford.EDU with TCP; 7 Sep 88 13:06:41 PDT
Received: from PURPLE.SWW.Symbolics.COM by WHITE.SWW.Symbolics.COM via CHAOS with CHAOS-MAIL id 206738; Wed 7-Sep-88 13:01:32 PDT
Date: Wed, 7 Sep 88 13:02 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Subject: Re: Hash Tables and GC
To: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>, Gregor.pa@Xerox.COM,
goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
Fcc: W:>ddyer>mail.sent.newest
In-Reply-To: <19880907194934.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Message-ID: <19880907200206.8.DDYER@PURPLE.SWW.Symbolics.COM>
Date: Wed, 7 Sep 88 15:49 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Date: Wed, 7 Sep 88 11:52 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Just to throw a little light into this discussion: On Symbolics systems there
is a list of forms to be evaluated before any gc flip (ephemeral or dynamic).
It's possible to implement whatever kind of weak pointers strategy you want by
explicitly clearing whatever pointers are "weak" before the flip occurs. The
list is called SI:GC-EVERY-FLIP-LIST
How does this tell you whether there *are* any non-weak pointers to the
object in question?
The main point of the desire for weak pointers is to free storage being
held by the pointers. SI:GC-EVERY-FLIP-LIST can't tell you that
removing a pointer will definitely free storage, but it does let you
remove pointers that you don't need and that you know will probably free
storage.
For example, I've used it to empty the free pool of a resource, and I've
used it to "clean" a cache of all obsolete items.
∂07-Sep-88 1310 Common-Lisp-mailer weak pointers vs temporary hash tables
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 7 Sep 88 13:10:43 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Wed, 7 Sep 88 16:11:39 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 7 Sep 88 16:08:48 EDT
Date: Wed, 7 Sep 88 16:05 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: weak pointers vs temporary hash tables
To: common-lisp@sail.stanford.edu
Message-Id: <19880907200516.0.BARMAR@OCCAM.THINK.COM>
This discussion we've been having keeps going between temporary hash
tables and weak pointers, and the implication of the latter discussion
seemed to be that weak pointers are all you need for temporary hash
tables. I'm not sure this is so.
For temporary hash tables, special measures need to be taken when a weak
key is GCed. You can't just set the key slot of the table entry to NIL.
First of all, it would be nice to also nullify the value slot of an
entry whose key is GCed, so that the value can be GCed. This could be
done by high-level code outside the GC, though. A more significant
problem is that most hash table mechanisms need to be able to
distinguish never-used table entries from deleted table entries. Also,
just setting the key field to NIL is no good, because NIL is a valid
key. The mechanism for invalidating weak pointers to garbage must
therefore be cognizant of the high-level structure containing the weak
pointer.
barmar
∂07-Sep-88 1323 Common-Lisp-mailer Re: Hash Tables and GC
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Sep 88 13:22:37 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 455750; Wed 7-Sep-88 16:18:27 EDT
Date: Wed, 7 Sep 88 16:17 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Re: Hash Tables and GC
To: DDYER@RIVERSIDE.SCRC.Symbolics.COM, Greenwald@STONY-BROOK.SCRC.Symbolics.COM,
Gregor.pa@Xerox.COM, goldman@vaxa.isi.edu
cc: COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: <19880907200206.8.DDYER@PURPLE.SWW.Symbolics.COM>
Message-ID: <19880907201756.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Wed, 7 Sep 88 13:02 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Date: Wed, 7 Sep 88 15:49 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Date: Wed, 7 Sep 88 11:52 PDT
From: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Just to throw a little light into this discussion: On Symbolics systems there
is a list of forms to be evaluated before any gc flip (ephemeral or dynamic).
It's possible to implement whatever kind of weak pointers strategy you want by
explicitly clearing whatever pointers are "weak" before the flip occurs. The
list is called SI:GC-EVERY-FLIP-LIST
How does this tell you whether there *are* any non-weak pointers to the
object in question?
The main point of the desire for weak pointers is to free storage being
held by the pointers.
weak-pointers also allow you to hold on to a pointer that may be useful
if and only if someone else is also interested in the object. If
"strong" pointers exist to the object then you definitely want to keep a
weak pointer to it. If not, you could have just cleared the pointer at
any point and it would have been GC'd in the next flip.
SI:GC-EVERY-FLIP-LIST can't tell you that
removing a pointer will definitely free storage, but it does let you
remove pointers that you don't need and that you know will probably free
storage.
For example, I've used it to empty the free pool of a resource, and I've
used it to "clean" a cache of all obsolete items.
∂07-Sep-88 1401 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 7 Sep 88 14:00:49 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa07948; 7 Sep 88 21:25 BST
Date: Wed, 7 Sep 88 21:54:04 BST
Message-Id: <21717.8809072054@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Implementing :TEMPORARY hash tables at the Lisp level?
To: Barry Margolin <barmar@think.com>
Cc: common-lisp@sail.stanford.edu
> Date: Wed, 7 Sep 88 18:26:30 BST
> From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
>
> Functions can be compared with EQ, EQL, and EQUAL,
>
> Function objects can, but not the results of invocations of the FUNCTION
> special form. On p.89, CLtL says, "a perfectly valid implementation
> might simply cause every distinct evaluation of a FUNCTION form to
> produce a new closure object not EQ to any other."
Well, (FUNCTION F) where there is no local function binding of F is
supposedly equivalent to (SYMBOL-FUNCTION 'F); and this is what I had
in mind when comparing with #'EQ.
So a question is: can SYMBOL-FUNCTION return a new object each time?
If so, I think this should be changed since it is clearly pointless.
And, if
(let ((f #'(lambda () 1))) (eq f f)) => t
[and it had better], then
(flet ((f () 1)) (eq #'f #'f)) should => t
[though I agree that CLtL does not say it will or should => T].
> The precise behavior
> of the FUNCTION special form in this regard will frequently depend on
> whether the code is compiled or interpreted and whether the argument is
> a global function name, a local function name, or a lambda expression.
>
> For example, in Symbolics Common Lisp the function
>
> (defun fn-eq-test (a)
> (flet ((internal () (cons a a)))
> (eq #'internal #'internal)))
>
> returns NIL when interpreted, but T when compiled. The interpreter
> definition of FUNCTION simply makes a new lexical closure, while the
> compiler collapses equivalent lexical closures.
Because of the LET analogy above, I do not see any need to have FUNCTION
make a new closure when its argument is a symbol. When the argument is
a LAMBDA-expression, then "is it really the same" becomes more difficult,
and I can see an interpreter (or compiler) taking a shortcut.
That is: FLET should be the one taking the shortcut for symbols, not
FUNCTION.
I suppose this would be harder to describe, though.
-- Jeff
∂07-Sep-88 1411 Common-Lisp-mailer weak pointers vs temporary hash tables
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 7 Sep 88 14:11:18 PDT
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 455802; Wed 7-Sep-88 17:07:17 EDT
Date: Wed, 7 Sep 88 17:06 EDT
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: weak pointers vs temporary hash tables
To: barmar@Think.COM, common-lisp@sail.stanford.edu
In-Reply-To: <19880907200516.0.BARMAR@OCCAM.THINK.COM>
Message-ID: <19880907210643.8.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Wed, 7 Sep 88 16:05 EDT
From: Barry Margolin <barmar@Think.COM>
This discussion we've been having keeps going between temporary hash
tables and weak pointers, and the implication of the latter discussion
seemed to be that weak pointers are all you need for temporary hash
tables. I'm not sure this is so.
Weak pointers + finalization.
For temporary hash tables, special measures need to be taken when a weak
key is GCed. You can't just set the key slot of the table entry to NIL.
First of all, it would be nice to also nullify the value slot of an
entry whose key is GCed, so that the value can be GCed. This could be
done by high-level code outside the GC, though. A more significant
problem is that most hash table mechanisms need to be able to
distinguish never-used table entries from deleted table entries. Also,
just setting the key field to NIL is no good, because NIL is a valid
key. The mechanism for invalidating weak pointers to garbage must
therefore be cognizant of the high-level structure containing the weak
pointer.
That's what finalization is for. The finalization function really has
to be per pointer. Maybe that means that an explicit form is needed to
dereference a weak-pointer (this would be invisible to users of
temporary hash tables but visible to clients of the subprimitives).
This would probably need to be done anyway, since when you pass an
object referenced through a weak pointer to another function, you
probably want to pass the strong pointer.
In any case, I don't see why this is a problem. When you are about to
free an object in a temporary table, you call the finalization function
on it. The finalization function for this particular weak-pointer is
probably a closure that is closed over the table, and fixes up the
key-field - i.e. it is cognizant of the high-level structure containing
the weak pointer.
barmar
∂08-Sep-88 0542 Common-Lisp-mailer Comparing functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 8 Sep 88 05:42:50 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab25423; 8 Sep 88 8:22 EDT
Received: from draper.com by RELAY.CS.NET id ae21239; 8 Sep 88 8:02 EDT
Date: Thu, 8 Sep 88 07:47 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Comparing functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: IN%"common-lisp@sail.stanford.edu"
From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 8-SEP-1988 07:30
To: IN%"jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.UK",SEB1525
Subj: RE: Re: Implementing :TEMPORARY hash tables at the Lisp level?
Well, as was already pointed out, an implementation may be creating new
objects every time #' is done, and it may not be trivial to optimize this
on the part of the compiler. There's gotta be a better way...
∂08-Sep-88 0801 Common-Lisp-mailer Re: Comparing functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 8 Sep 88 08:00:25 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05090; 8 Sep 88 15:19 BST
Date: Thu, 8 Sep 88 15:50:07 BST
Message-Id: <18347.8809081450@aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Comparing functions
To: "Steve Bacher (Batchman)" <SEB1525%draper.com@NSS.Cs.Ucl.AC.UK>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Thu, 8 Sep 88 07:47 EDT
> From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 8-SEP-1988 07:30
> To: IN%"jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.UK",SEB1525
> Subj: RE: Re: Implementing :TEMPORARY hash tables at the Lisp level?
>
> Well, as was already pointed out, an implementation may be creating new
> objects every time #' is done, and it may not be trivial to optimize this
> on the part of the compiler. There's gotta be a better way...
I think it *is* trivial to optimize #'F when F is a symbol. Simply
return the value of F in the function namespace: this function should
already exist and should not have to be copied or remade.
Comparison between different results of #'(LAMBDA ...), however, will
always be problematic because we want to allow certain optimizations
which will depend on what side-effects occur in the lambda-expression
and because it is not possible to compare arbitrary functions in general.
-- Jeff
∂09-Sep-88 2044 Common-Lisp-mailer Comparing functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 9 Sep 88 20:44:14 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa26552; 9 Sep 88 19:09 EDT
Received: from draper.com by RELAY.CS.NET id ab03033; 9 Sep 88 18:53 EDT
Date: Fri, 9 Sep 88 17:13 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Comparing functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
In looking at the definition for make-hash-table, I contend that a valid
implementation has no need for function-comparing primitives. It does
say that the :test argument "must be one of the threee values
#'eq, #'eql, or #'equal, or one of the three symbols eq, eql, or equal".
However, as I understand it, "must be" is equivalent to
"It is an error if not...", which means that the implementation doesn't
have to do anything if the :test argument happens to be something else.
Presumably, the compiler can source-level-optimize calls to MAKE-HASH-TABLE
(as long as the :test argument is a constant) to enforce this, and in fact
can convert such calls to lower-level things (e.g. MAKE-HASH-TABLE-WITH-EQ-TEST
and the like, or what have you).
So if temporary hash tables need to test the :test argument, which they do,
they can't rely on MAKE-HASH-TABLE already having established the need for
the requisite primitive.
∂11-Sep-88 1007 Common-Lisp-mailer Re: Comparing functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 11 Sep 88 10:04:01 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa02927; 11 Sep 88 17:30 BST
Date: Sun, 11 Sep 88 18:01:03 BST
Message-Id: <2933.8809111701@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Comparing functions
To: "Steve Bacher (Batchman)" <SEB1525%draper.com@NSS.Cs.Ucl.AC.UK>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Fri, 9 Sep 88 17:13 EDT
> In looking at the definition for make-hash-table, I contend that a valid
> implementation has no need for function-comparing primitives.
That is expected since function comparing primitives that determine "do
these compute the same function" are impossible.
> It does say that the :test argument "must be one of the threee values
> #'eq, #'eql, or #'equal, or one of the three symbols eq, eql, or equal".
I am assuming you agree that MAKE-HASH-TABLE does need some way to
determine whether the :TEST argument is EQ, #'EQ, EQL, #'EQL, EQUAL
or #'EQUAL, because it does, of course, need some way to do this.
> So if temporary hash tables need to test the :test argument, which they do,
> they can't rely on MAKE-HASH-TABLE already having established the need for
> the requisite primitive.
Yes they can.
They do not need any other test than whatever means MAKE-HASH-TABLE
uses to determine whether to make an EQ table or an EQL or EQUAL one.
-- Jeff
∂11-Sep-88 1014 Common-Lisp-mailer Re: Hash Tables and GC
Received: from JASPER.SCRC.Symbolics.COM ([128.81.41.58]) by SAIL.Stanford.EDU with TCP; 11 Sep 88 10:14:53 PDT
Received: from KOYAANISQATSI.SCRC.Symbolics.COM by JASPER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 215657; Sun 11-Sep-88 13:13:55 EDT
Date: Sun, 11 Sep 88 13:12 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Subject: Re: Hash Tables and GC
To: Gregor.pa@Xerox.COM
cc: goldman@vaxa.isi.edu, COMMON-LISP@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: <19880907025057.5.GREGOR@PORTNOY.parc.xerox.com>
Message-ID: <19880911171244.3.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Date: Tue, 6 Sep 88 19:50 PDT
From: Gregor.pa@Xerox.COM
As I understand it, finalization is a mechanism for recording a function
which the garbage collector should call on an object when it is about to
be GC'd.
I find it surprising that no one has talked about finalization during
this discussion. This may not be facility we want to add to Common
Lisp, but as near as I can tell, weak pointers and finalization are the
primitives you need to build these kind of hash tables.
In addition, finalization is a useful mechanism to have direct access
to.
Finalization is certainly useful, but I'm not sure how any
implementation of a copying GC could implement it. This is because the
function has to be called on an object which is in oldspace but it
cannot migrate the object to copyspace before examining it.
In a GC with hardware assistance, you have to bypass the transport
hardware to do this, which means you have to specially write the
function using implementation-dependent primitives. (Note that
"conventional processors" may use "hardware assistance" such as read and
write traps.) In all GCs, you have to ensure that the finalization
function does not cause a pointer to oldspace to be stored into anyplace
in memory. This itself is a fairly severe restriction; it is certainly
not the same as "side-effect-free", but it is close.
I understand how to implement this feature, but I don't see how to do it
in an implemention-independent fashion in a copying garbage collector.
This is significant since most garbage collectors on the market today
are copying garbage collectors. I also don't understand how to make it
safe enough to be a language feature.
∂12-Sep-88 0522 Common-Lisp-mailer Comparing functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 Sep 88 05:22:27 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa23495; 12 Sep 88 8:17 EDT
Received: from draper.com by RELAY.CS.NET id ae14648; 12 Sep 88 8:06 EDT
Date: Mon, 12 Sep 88 07:21 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Comparing functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
Yes, I knew the case code wouldn't work as written. It was intended tobe
an absurd example, being (in my opinion) impossible to write correctly in CL.
∂12-Sep-88 0522 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 12 Sep 88 05:22:18 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa23444; 12 Sep 88 8:11 EDT
Received: from draper.com by RELAY.CS.NET id ac14648; 12 Sep 88 8:06 EDT
Date: Mon, 12 Sep 88 07:18 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: MAKE-HASH-TABLE :TEST arg
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP
From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 12-SEP-1988 07:15
To: IN%"jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.UK",SEB1525
Subj: RE: Re: Comparing functions
Er, my point was that MAKE-HASH-TABLE doesn't absolutely need to do that test.
Why can't a valid implementation of MAKE-HASH-TABLE just blindly FUNCALL the
TEST argument? If you can explain to me what different frobulations it needs
to set up based on the TEST argument, I will be convinced. Otherwise, I
remain.....
∂12-Sep-88 0807 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 12 Sep 88 08:07:08 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 12 Sep 88 11:04:51 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 12 Sep 88 11:04:54 EDT
Date: Mon, 12 Sep 88 11:05 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: MAKE-HASH-TABLE :TEST arg
To: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8809121223.AA00923@Think.COM>
Message-Id: <19880912150515.9.BARMAR@OCCAM.THINK.COM>
Date: Mon, 12 Sep 88 07:18 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
From: CCFVX3::SEB1525 "Steve Bacher (Batchman)" 12-SEP-1988 07:15
To: IN%"jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.UK",SEB1525
Subj: RE: Re: Comparing functions
Er, my point was that MAKE-HASH-TABLE doesn't absolutely need to do that test.
Why can't a valid implementation of MAKE-HASH-TABLE just blindly FUNCALL the
TEST argument? If you can explain to me what different frobulations it needs
to set up based on the TEST argument, I will be convinced. Otherwise, I
remain.....
Various aspects of the behavior of a hash table are dependent upon the
TEST argument. An EQUAL hash table need not be rehashed after a copying
GC. The hash function is generally dependent upon the test function;
for an EQUAL hash table it would be SXHASH, while for an EQ hash table
it would probably be a simple hash on the address.
I suppose you COULD use SXHASH for all hash tables, since EQ objects are
necessarily EQUAL, and you COULD rehash ALL hash tables. Or you could
implement hash tables without actually hashing (e.g. implement them as
alists). But if performance is an issue (which it generally is when you
use a hash table), you'll probably want to do things dependent on the
test function.
barmar
∂12-Sep-88 1146 Common-Lisp-mailer Hash Tables and GC
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 12 Sep 88 11:46:36 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA12250; Mon, 12 Sep 88 11:41:17 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0)
id AA18046; Mon, 12 Sep 88 11:44:09 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA11669; Mon, 12 Sep 88 10:37:32 PDT
Date: Mon, 12 Sep 88 10:37:32 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8809121737.AA11669@lukasiewicz.sun.com>
To: DLA@JASPER.SCRC.Symbolics.COM
Cc: Gregor.pa@Xerox.COM, goldman@vaxa.isi.edu, COMMON-LISP@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: David L. Andre's message of Sun, 11 Sep 88 13:12 EDT <19880911171244.3.DLA@KOYAANISQATSI.SCRC.Symbolics.COM>
Subject: Hash Tables and GC
Date: Sun, 11 Sep 88 13:12 EDT
From: David L. Andre <DLA@JASPER.SCRC.Symbolics.COM>
Date: Tue, 6 Sep 88 19:50 PDT
From: Gregor.pa@Xerox.COM
As I understand it, finalization is a mechanism for recording a function
which the garbage collector should call on an object when it is about to
be GC'd.
I find it surprising that no one has talked about finalization during
this discussion. This may not be facility we want to add to Common
Lisp, but as near as I can tell, weak pointers and finalization are the
primitives you need to build these kind of hash tables.
In addition, finalization is a useful mechanism to have direct access
to.
... the function has to be called on an object which is in oldspace but it
cannot migrate the object to copyspace before examining it.
...
I understand how to implement this feature, but I don't see how to do it
in an implemention-independent fashion in a copying garbage collector.
This is significant since most garbage collectors on the market today
are copying garbage collectors. I also don't understand how to make it
safe enough to be a language feature.
There is a single answer to both those questions: Don't treat the
object any differently under after the finalization function has
run. This means that unfinalized objects get moved to copyspace,
and so take two GC cycles to free. (This is an acceptable cost,
to my mind: You just pay double for finalizable memory.)
Here's how it would work from the client's point of view: Finalizable
objects have a single bit of client-alterable state FINALIZABLE-P. When
the GC is about to collect an object with this bit turned on, it instead
preserves the object in a central place. After the GC has finished
running, all such objects get their FINALIZABLE-P bits turned off,
and they are then passed to their various finalization functions.
Those functions, in turn are free to manipulate the FINALIZABLE-P
bit; if after finalization the bit is turned off, and no references
remain, the next GC will treat the object like any other piece of
garbage.
Note that this model does not refer to exact nature of the underlying GC
technology. It simply assumes there is a simple way to implement the
FINALIZABLE-P bit. Note that if another GC happens while a finalization
function is running, even though the object's FINALIZABLE-P bit is
turned off, the object is retained, since it is referenced from the
stack.
It is not obvious to me when weak pointers to objects undergoing
finalization should be cleared. I can think of cases supporting
either choice, of clearing the pointers during the first GC,
or during the second. I lean towards clearing them during the
first GC, when the objects are being placed on the FINALIZATIONS
list.
Here's how you could implement this in a copying GC: In addition to a
FINALIZABLE-P bit, there is in fact a hidden slot called
FINALIZEABLE-CHAIN in the layout of finalizable objects. (The bit can
maiybe be stored somewhere in the slot, instead of a tag.) This slot
forms a linked list FINALIZABLE-LIST of all objects needing
finalization. When the client turns the FINALIZABLE-P bit off, the
system is free to remove the object from the linked list when
convenient. When the client turns the bit on, the system must ensure
that they are once again on the list. At GC time, oldspace is scanned
as usual, but FINALIZABLE-LIST is not used as a root reference, nor is
the FINALIZABLE-CHAIN slot used to propagate referencing. Just before
oldspace is flushed, however, FINALIZABLE-LIST is now used as a root
reference. Any objects which are moved to copyspace at this time are
objects needing finalization. Such objects are unlinked from the
FINALIZABLE-LIST (which by now is in newspace) but are placed on another
list called FINALIZATIONS. It is this list that is traversed after the
GC, to call the finalization functions.
Note that these functions are called after the GC has finished
reconstructing the heap in copyspace. In fact, there is no need to call
them immediately after the GC; the list could be processed at any
opportune moment, perhaps in a low-priority background process.
Some provision must be made to retain the FINALIZATIONS list across GCs
occurring during the actual process of finalization. The simplest thing
to do is leave their FINALIZABLE-P bit turned on, so intervening GCs
just re-collect the FINALIZATIONS list from scratch.
By the way, a clean way to introduce finalization into CLOS would be to
have a finalizable superclass, which contained the hidden
FINALIZABLE-CHAIN slot, and supported an accessor for the FINALIZABLE-P
bit. The generic function FINALIZE would be called to finalize such
objects, and subclasses could specialize it.
This design implies that some kinds of objects (e.g., cons cells) are
not finalizable; that's fine with me. I use finalization, in C++,
mainly to deallocate memory when I'm done with it. Lisp takes care of
that task, but there are other resources which both C++ and Lisp
finalization help manage, notably operating system channels for open
streams. (Other examples: Temporary files or disk blocks, and resources
in coprocessors or servers.) Therefore, finalization typically applies
to an object which serves as a container for the non-Lisp resources, and
it doesn't disturb me that such objects are a limited subset of all
possible Lisp objects.
-- John
∂12-Sep-88 1248 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Sep 88 12:48:02 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 457774; 12 Sep 88 15:46:35 EDT
Date: Mon, 12 Sep 88 15:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: MAKE-HASH-TABLE :TEST arg
To: Barry Margolin <barmar@Think.COM>
cc: "Steve Bacher (Batchman)" <SEB1525@draper.com>, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880912150515.9.BARMAR@OCCAM.THINK.COM>
Supersedes: <19880912194413.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Comments: sent original version with equality where I meant equivalence
Message-ID: <19880912194542.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 12 Sep 88 11:05 EDT
From: Barry Margolin <barmar@Think.COM>
I suppose you COULD use SXHASH for all hash tables, since EQ objects are
necessarily EQUAL
Not if the following program is valid Common Lisp. I couldn't find anything
in CLtL that speaks to this. Should this be run through the cleanup committee?
(setq ht (make-hash-table :test #'eq))
(setq a (cons 1 2))
(setf (gethash a ht) 'win)
(setf (cdr a) 3)
(gethash a ht 'lose) => win t
If SXHASH was used, the last form would evaluate to lose nil unless
by chance (= (sxhash '(1 . 2)) (sxhash '(1 . 3))) was true or by
chance the structure of the hash table was such that the difference
between the two sxhash values did not matter. Similar
examples can be constructed using strings and bit-vectors in place of
conses.
I would propose that modifications to components of the key do not
affect EQ and EQL hash tables, and thus are allowed, but are not
allowed for EQUAL hash tables when the modification is to a component
that is examined by the EQUAL function.
∂12-Sep-88 1249 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 12 Sep 88 12:49:16 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 457773; Mon 12-Sep-88 15:45:03 EDT
Date: Mon, 12 Sep 88 15:44 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: MAKE-HASH-TABLE :TEST arg
To: Barry Margolin <barmar@Think.COM>
cc: "Steve Bacher (Batchman)" <SEB1525@draper.com>, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: <19880912150515.9.BARMAR@OCCAM.THINK.COM>
Message-ID: <19880912194413.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Mon, 12 Sep 88 11:05 EDT
From: Barry Margolin <barmar@Think.COM>
I suppose you COULD use SXHASH for all hash tables, since EQ objects are
necessarily EQUAL
Not if the following program is valid Common Lisp. I couldn't find anything
in CLtL that speaks to this. Should this be run through the cleanup committee?
(setq ht (make-hash-table :test #'eq))
(setq a (cons 1 2))
(setf (gethash a ht) 'win)
(setf (cdr a) 3)
(gethash a ht 'lose) => win t
If SXHASH was used, the last form would evaluate to lose nil unless
by chance (= (sxhash '(1 . 2)) (sxhash '(1 . 3))) was true. Similar
examples can be constructed using strings and bit-vectors in place of
conses.
I would propose that modifications to components of the key do not
affect EQ and EQL hash tables, and thus are allowed, but are not
allowed for EQUAL hash tables when the modification is to a component
that is examined by the EQUAL function.
∂12-Sep-88 1347 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 12 Sep 88 13:47:23 PDT
Received: from edsel ([192.9.200.1]) by heavens-gate.lucid.com id AA00469g; Mon, 12 Sep 88 12:39:26 PST
Site:
Received: from blacksox.lucid.com by edsel id AA00955g; Mon, 12 Sep 88 13:32:38 PDT
Received: by blacksox id AA00162g; Mon, 12 Sep 88 13:35:18 pdt
Date: Mon, 12 Sep 88 13:35:18 pdt
From: Eric Benson <eb@lucid.com>
Message-Id: <8809122035.AA00162@blacksox.lucid.com>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: barmar@Think.COM, SEB1525@draper.com, common-lisp@SAIL.STANFORD.EDU
In-Reply-To: David A. Moon's message of Mon, 12 Sep 88 15:45 EDT <19880912194542.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: MAKE-HASH-TABLE :TEST arg
Date: Mon, 12 Sep 88 15:45 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
I would propose that modifications to components of the key do not
affect EQ and EQL hash tables, and thus are allowed, but are not
allowed for EQUAL hash tables when the modification is to a component
that is examined by the EQUAL function.
This makes sense, since EQ and EQL hash tables use the identity of the
object as the key, while EQUAL hash tables use the structure of the
object as the key. Component modification changes the structure of an
object, while the identity of an object cannot be changed in Common
Lisp. On p.168 of CLtL the following comment is found under
SYMBOL-NAME:
"It is an extremely bad idea to modify a string being used as the
print name of a symbol. Such a modification may tremendously confuse
the function READ and the package system."
This should be generalized to apply to any object which is used as a
key in an EQUAL hash table.
∂12-Sep-88 1556 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 12 Sep 88 15:56:00 PDT
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Mon, 12 Sep 88 18:53:14 EDT
Received: from OCCAM.THINK.COM by sauron.think.com; Mon, 12 Sep 88 18:53:54 EDT
Date: Mon, 12 Sep 88 18:54 EDT
From: Barry Margolin <barmar@Think.COM>
Subject: MAKE-HASH-TABLE :TEST arg
To: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Cc: "Steve Bacher (Batchman)" <SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: <19880912194542.1.MOON@EUPHRATES.SCRC.Symbolics.COM>
Message-Id: <19880912225417.5.BARMAR@OCCAM.THINK.COM>
Date: Mon, 12 Sep 88 15:45 EDT
From: David A. Moon <Moon@stony-brook.scrc.symbolics.com>
Date: Mon, 12 Sep 88 11:05 EDT
From: Barry Margolin <barmar@Think.COM>
I suppose you COULD use SXHASH for all hash tables, since EQ objects are
necessarily EQUAL
Not if the following program is valid Common Lisp. I couldn't find anything
in CLtL that speaks to this. Should this be run through the cleanup committee?
(setq ht (make-hash-table :test #'eq))
(setq a (cons 1 2))
(setf (gethash a ht) 'win)
(setf (cdr a) 3)
(gethash a ht 'lose) => win t
If SXHASH was used, the last form would evaluate to lose nil unless
by chance (= (sxhash '(1 . 2)) (sxhash '(1 . 3))) was true or by
chance the structure of the hash table was such that the difference
between the two sxhash values did not matter. Similar
examples can be constructed using strings and bit-vectors in place of
conses.
I would propose that modifications to components of the key do not
affect EQ and EQL hash tables, and thus are allowed, but are not
allowed for EQUAL hash tables when the modification is to a component
that is examined by the EQUAL function.
You're right.
barmar
∂13-Sep-88 0623 Common-Lisp-mailer MAKE-HASH-TABLE :TEST arg
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 13 Sep 88 06:23:28 PDT
Received: from relay2.cs.net by RELAY.CS.NET id af06011; 13 Sep 88 8:20 EDT
Received: from draper.com by RELAY.CS.NET id aa23004; 13 Sep 88 8:13 EDT
Date: Tue, 13 Sep 88 07:40 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: MAKE-HASH-TABLE :TEST arg
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
Please don't CC to me. I am getting 2 copies of all your flames due to
being on common-lisp. Thanks. - "Steve Bacher"
∂14-Sep-88 1404 Common-Lisp-mailer Profiling lisp
Received: from PROOF.ERGO.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 14 Sep 88 14:04:31 PDT
Received: from PROOF.ERGO.CS.CMU.EDU by PROOF.ERGO.CS.CMU.EDU; 14 Sep 88 17:02:25 EDT
To: common-lisp@sail.stanford.edu
cc: Kenneth.Cline@PROOF.ERGO.CS.CMU.EDU
Subject: Profiling lisp
Date: Wed, 14 Sep 88 17:02:19 EDT
Message-ID: <26018.590274139@PROOF.ERGO.CS.CMU.EDU>
From: Conal.Elliott@PROOF.ERGO.CS.CMU.EDU
Does anyone have ideas, or preferably code, to profile Lisp code, i.e., to find
out how much time is being spent where?
We are using Lucid Common Lisp 2.1.1. I'll post a summary of my results.
Thanks!
- Conal
∂14-Sep-88 1753 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 14 Sep 88 17:53:25 PDT
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00781g; Wed, 14 Sep 88 16:50:32 PST
Received: by bhopal id AA07298g; Wed, 14 Sep 88 17:49:57 PDT
Date: Wed, 14 Sep 88 17:49:57 PDT
From: Jon L White <jonl@lucid.com>
Message-Id: <8809150049.AA07298@bhopal>
To: barmar@Think.COM
Cc: SEB1525@draper.com, common-lisp@sail.stanford.edu,
jeff@aiai.edinburgh.ac.uk
In-Reply-To: Barry Margolin's message of Wed, 7 Sep 88 12:07 EDT <19880907160730.3.BARMAR@OCCAM.THINK.COM>
Subject: Implementing :TEMPORARY hash tables at the Lisp level?
[I've read ahead to look at other comments on this issue, and will try
to coordinate my comments on several such messages.]
First, I think someone already pointed out that CASE is not the proper
common lisp construct to use since:
(case x ((#'eq #'equal) ...))
is simply equivalent to:
(case x (((function eq) (function equal)) ...))
and one definitely doesn't intend to compare the value of x with some
"internal" list (function eq)! [Query: should an implementation give
you a warning msg when finding such a situation in CASE?]
re: The internal implementation of a Common Lisp need not be written using
portable constructs.
Right. In fact, Interlisp did "cons" up a new value each time you
called the equivalent of SYMBOL-FUNCTION, because the function cell
did _not_ contain a Lisp object, but something more hardware and/or
firmware specific. Of course, access and update of that cell is via a
functional interface, which "mediates" between the expected type of
value and that actually stored in memory. Thus in that implmentation:
(eq #'eq #'eq)
would be guaranteed not to work the way this discussion has been assuming
it to work. Consequently, Interlisp had the function EQP -- somewhat a
forerunner of the Common Lisp EQL -- which would tell you when two
different "compiled code pointers" were in fact pointing to the same piece
of compiled code, but would simply be EQ on most other cases. [I don't
know how XAIS/ENVOS's Common Lisp product handles this matter; probably
something less tied to the tricks "firmware".]
re: I suspect that in most CL implementations, #'<symbol> always returns the
same thing for symbols that do not have a lexical function binding, so
the above code would work.
Sigh, I wish you were right. I know of at least one implmenetation where
(function <symbol>) simply acts like (quote <symbol>); although this
"always returns the same thing", it definitely isn't what you expect
[i.e., it would not be FUNCTIONP under the revised x3j13 sense.]
I think it would be a good idea for an X3J13 "Cleanup" to address this.
My first thought would be like yours -- that #'<symbol> in the absence of
lexical overrides return a unique pointer for as long as the function
remains the same. Still, we would have to hear from the vendors for which
this would be an incompatible change. It wouldn't be outlandish to let
this fall into the realm of EQL -- just at Interlisp used EQP -- and extend
EQL to cover "function" objects as well as numbers and characters.
-- JonL --
∂14-Sep-88 1853 Common-Lisp-mailer Hash Tables and GC
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 14 Sep 88 18:53:37 PDT
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00834g; Wed, 14 Sep 88 17:51:10 PST
Received: by bhopal id AA07576g; Wed, 14 Sep 88 18:50:35 PDT
Date: Wed, 14 Sep 88 18:50:35 PDT
From: Jon L White <jonl@lucid.com>
Message-Id: <8809150150.AA07576@bhopal>
To: DDYER@RIVERSIDE.SCRC.Symbolics.COM
Cc: Greenwald@STONY-BROOK.SCRC.Symbolics.COM, Gregor.pa@Xerox.COM,
goldman@vaxa.isi.edu, COMMON-LISP@sail.stanford.edu,
jeff%aiai.edinburgh.ac.uk@nss.cs.ucl.ac.uk
In-Reply-To: DDYER@RIVERSIDE.SCRC.Symbolics.COM's message of Wed, 7 Sep 88 11:52 PDT <19880907185230.5.DDYER@PURPLE.SWW.Symbolics.COM>
Subject: Hash Tables and GC
re: Just to throw a little light into this discussion: On Symbolics systems
there is a list of forms to be evaluated before any gc flip (ephemeral or
dynamic). It's possible to implement whatever kind of weak pointers
strategy you want by explicitly clearing whatever pointers are "weak"
before the flip occurs. The list is called SI:GC-EVERY-FLIP-LIST
Hmmmmm. As barmar points out, this could't work _in general_ for weak
pointers unless you also restore the non-GC'd entries that you deleted.
PDP10 MacLisp provided a different variant of this -- the infamous GC
hook [sigh, there were so many "hooks" in MacLisp!]. Just _after_ a GC
finishs, but before any more consing is done, the user's "hook" function
is run. At this unique interval in time, it is possible to ask of a random
address/pointer "Were you just GC'd"; [in fact, this capability is independent
of whether it is a copying, or collecting or refcnt'ing GC]. Then using NIL
type arrays, pointers could be kept around for inspection after the GC; the
"NIL type" array simply means that the GC doesn't mark or descend the entries
(just like XPOINTER type arrays in Interlisp-D].
GJS used this hook to good advantage in MicroPlanner and early Scheme
implementations. In effect, I think he implemnted :temporary type
hash tables.
-- JonL --
∂15-Sep-88 0909 Common-Lisp-mailer (eq #'eq #'eq)
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Sep 88 09:09:45 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa24766; 15 Sep 88 10:45 EDT
Received: from draper.com by RELAY.CS.NET id aa09139; 15 Sep 88 10:34 EDT
Date: Thu, 15 Sep 88 07:26 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: (eq #'eq #'eq)
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
Thanks, JonL. I was pleased to hear that it is conceivable for a valid CL
implementation not necessarily to return the same object for
(SYMBOL-FUNCTION foo) all the time. This has ramifications for
autoloading schemes: if the function definition for a symbol FOO is
autoloaded, then the initial contents of the "function cell" of FOO would
contain a FOO-autoloader, or perhaps some kind of null value; therefore
just loading up the function cell twice would not result in the same (EQ)
pointer under such circumstances. Such freedom is probably necessary in
order to support function autoloading on (formerly much-maligned until
recent developments in the business world) "stock hardware".
∂15-Sep-88 1040 Common-Lisp-mailer Implementing :TEMPORARY hash tables at the Lisp level?
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 15 Sep 88 10:40:44 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 459766; Thu 15-Sep-88 13:37:06 EDT
Date: Thu, 15 Sep 88 13:36 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Implementing :TEMPORARY hash tables at the Lisp level?
To: Jon L White <jonl@lucid.com>
cc: barmar@Think.COM, SEB1525@draper.com, common-lisp@sail.stanford.edu,
jeff@aiai.edinburgh.ac.uk
In-Reply-To: <8809150049.AA07298@bhopal>
Message-ID: <19880915173625.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Date: Wed, 14 Sep 88 17:49:57 PDT
From: Jon L White <jonl@lucid.com>
My first thought would be like yours -- that #'<symbol> in the absence of
lexical overrides return a unique pointer for as long as the function
remains the same. Still, we would have to hear from the vendors for which
this would be an incompatible change.
I know of at least one case in Symbolics Common Lisp where (eq #'foo #'foo)
returns false. However, foo was defined with a non-Common-Lisp construct
(defun-in-flavor). It wouldn't surprise me to learn that there are
implementations where the same thing happens when foo was defined with
FLET, in cases where the surrounding lexical environment structure is
sufficiently complex. As you pointed out, the same thing can happen with
functions defined globally, in the implementation technique used in
Interlisp-10.
One could see how to add hair to a compiler to avoid these situations, but
it may be infeasible in an interpreter.
I remember a discussion among the Scheme folks on these issues a few
years ago, which I think came to the conclusion that EQ cannot be
well-defined on closures. Two closures that look different, but can be
proved equivalent by an optimizing compiler, might end up EQ, and two
closures of the same function in what the user imagines to be the same
environment might end up distinct due to an optimizing compiler (stack
allocation) or a non-optimizing interpreter or compiler.
However, no one said that MAKE-HASH-TABLE's association from the :TEST
argument to the type of hashing has to be done with EQ. One approach
is to get the function's name and then look up the name in a table.
Another is to embed the type of hashing in the test function's
definition, using a declaration that causes the compiler to attach
data to the compiled code. Both of these rely on the fact that, at
least for the builtin hash functions, the type of hashing depends only
on the function and not on the environment in which it is enclosed.
It wouldn't be outlandish to let
this fall into the realm of EQL -- just at Interlisp used EQP -- and extend
EQL to cover "function" objects as well as numbers and characters.
I would resist this, as our hardware implementation of EQL would not be
capable of this extension. Aside from that somewhat parochial viewpoint,
if equivalence of closures is something different from EQ, I have trouble
figuring out what it would be defined as that would have any meaning
that was both portable and effectively computable.
∂15-Sep-88 1112 Common-Lisp-mailer Profiling lisp
Received: from MCC.COM by SAIL.Stanford.EDU with TCP; 15 Sep 88 11:12:29 PDT
Received: from CHOMOLUNGMA.ACA.MCC.COM (CHOMOLUNGMA.ACA.MCC.COM.#Chaos) by MCC.#Chaos with Chaos/SMTP; Thu 15 Sep 88 08:25:10-CDT
Date: Thu, 15 Sep 88 08:24 CDT
From: William D. Gooch <ai.gooch@MCC.COM>
Subject: Profiling lisp
To: Conal.Elliott%PROOF.ERGO.CS.CMU.EDU@MCC.COM
cc: common-lisp%sail.stanford.edu@MCC.COM, Kenneth.Cline%PROOF.ERGO.CS.CMU.EDU@MCC.COM
In-Reply-To: <26018.590274139@PROOF.ERGO.CS.CMU.EDU>
Message-ID: <19880915132456.7.GOOCH@CHOMOLUNGMA.ACA.MCC.COM>
Date: Wed, 14 Sep 88 17:02:19 EDT
From: Conal.Elliott@PROOF.ERGO.CS.CMU.EDU
Does anyone have ideas, or preferably code, to profile Lisp code, i.e., to find
out how much time is being spent where?
We are using Lucid Common Lisp 2.1.1. I'll post a summary of my results.
Thanks!
- Conal
I don't think this will help you, but: Symbolics has put an excellent
set of metering tools in their latest release (Genera 7.2).
∂15-Sep-88 1238 Common-Lisp-mailer Re: Implementing :TEMPORARY hash tables at the Lisp level?
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 15 Sep 88 12:36:48 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa06246; 15 Sep 88 19:09 BST
Date: Thu, 15 Sep 88 19:42:15 BST
Message-Id: <11304.8809151842@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Implementing :TEMPORARY hash tables at the Lisp level?
To: "David A. Moon" <Moon@scrc-stony-brook.arpa>,
Jon L White <jonl%lucid.com@NSS.Cs.Ucl.AC.UK>
In-Reply-To: David A. Moon's message of Thu, 15 Sep 88 13:36 EDT
Cc: barmar@think.com, SEB1525 <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu, jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
> I know of at least one case in Symbolics Common Lisp where (eq #'foo #'foo)
> returns false. However, foo was defined with a non-Common-Lisp construct
> (defun-in-flavor). It wouldn't surprise me to learn that there are
> implementations where the same thing happens when foo was defined with
> FLET, in cases where the surrounding lexical environment structure is
> sufficiently complex. As you pointed out, the same thing can happen with
> functions defined globally, in the implementation technique used in
> Interlisp-10.
>
> One could see how to add hair to a compiler to avoid these situations, but
> it may be infeasible in an interpreter.
Modulo certain efficiency considerations, as in Interlisp-10, I do not
think there is any particular difficulty in having (eq #'f #'f) return
true. Presumably, interpreters do not have any trouble with
(let ((f #'(lambda ...)))
(eq f f)) ==> t
Are there optimization considerations, as there are for numbers and
EQ, that argue against having EQ be well-defined to the extent of
being able to make comparisons such as (eq x #'eq) [which I think
is all that's needed for make-hash-table]?
∂15-Sep-88 1823 Common-Lisp-mailer Testing for #'eqness
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 15 Sep 88 18:23:44 PDT
Received: from relay2.cs.net by RELAY.CS.NET id am01919; 15 Sep 88 18:08 EDT
Received: from draper.com by RELAY.CS.NET id aa11476; 15 Sep 88 17:49 EDT
Date: Thu, 15 Sep 88 17:12 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Testing for #'eqness
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
Moon's suggestions are a real win. It is much better to test a function
passed to another function by means of "is-this-named-eq-p" or
"is-this-a-valid-hashing-test-function-p" than by trying to compare it
to whatever #'eq ends up as being in the tester function's code.
There are ways to screw the system, of course, like creating another
compiled function called EQ (check the package???), but who cares.
Let 'em screw the system if that's what they really want to do. :-)
∂16-Sep-88 0513 Common-Lisp-mailer EQness of functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 16 Sep 88 05:13:41 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab13370; 16 Sep 88 8:00 EDT
Received: from draper.com by RELAY.CS.NET id aa16695; 16 Sep 88 7:49 EDT
Date: Fri, 16 Sep 88 07:09 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: EQness of functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
The case of
(let ((f #'(lambda ...)))
(eq f f))
has no bearing on the issue of whether (eq f #'eq) is valid. #'eq means
(function eq), which may or may not result in something being done at
run time to evaluate it; f is a variable reference whose value has already
"been evaluated" at some prior time. (eq f f) ought to always be true,
modulo some kinds of number-optimization.
∂16-Sep-88 0551 Common-Lisp-mailer Re: (eq #'eq #'eq)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 16 Sep 88 05:51:31 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04457; 16 Sep 88 13:08 BST
Date: Fri, 16 Sep 88 13:41:31 BST
Message-Id: <442.8809161241@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: (eq #'eq #'eq)
To: common-lisp@sail.stanford.edu
In-Reply-To: System Files's message of 15 Sep 88 0909 PDT
> Date: Thu, 15 Sep 88 07:26 EDT
> From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
>
> Thanks, JonL. I was pleased to hear that it is conceivable for a valid CL
> implementation not necessarily to return the same object for
> (SYMBOL-FUNCTION foo) all the time. This has ramifications for
> autoloading schemes: if the function definition for a symbol FOO is
> autoloaded, then the initial contents of the "function cell" of FOO would
> contain a FOO-autoloader, or perhaps some kind of null value; therefore
> just loading up the function cell twice would not result in the same (EQ)
> pointer under such circumstances. Such freedom is probably necessary in
> order to support function autoloading on (formerly much-maligned until
> recent developments in the business world) "stock hardware".
Sigh. I don't really want to beat this issue to death, but I don't
think autoloading makes that much difference. You allow that the
initial contents might be "some kind of null value". That is very
like what will happen if the function is initially undefined.
(Indeed, some Lisps make autoloading part of the handling for
undefined functions.) Autoloading is very like defining or redefining
the function. And that is not much different from doing a SETQ.
But suppose (SYMBOL-FUNCTION F) does contain an autoloader.
Then either SYMBOL-FUNCTION does the autoloading itself
(and returns the real function) or else it returns the autoloader
function. Presumably it will do the same thing if called again,
and so (eq (symbol-function f) (symbol-function f)) will return
true.
My point is simply this: it would be nice if FUNCTION of a symbol were
simply a way to get the value of the symbol in the function namespace
Would you say Scheme can't support function autoloading?
-- Jeff
∂16-Sep-88 0939 Common-Lisp-mailer Re: EQness of functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 16 Sep 88 09:38:22 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05032; 16 Sep 88 14:45 BST
Date: Fri, 16 Sep 88 15:19:05 BST
Message-Id: <830.8809161419@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: EQness of functions
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Fri, 16 Sep 88 07:09 EDT
Cc:
> The case of
> (let ((f #'(lambda ...)))
> (eq f f))
> has no bearing on the issue of whether (eq f #'eq) is valid. #'eq means
> (function eq), which may or may not result in something being done at
> run time to evaluate it; f is a variable reference whose value has already
> "been evaluated" at some prior time. (eq f f) ought to always be true,
> modulo some kinds of number-optimization.
It is clear at least they we are not understanding each other.
I will try again nonetheless. The problem may be that I am
talking about what FUNCTION should be and you seem to be talking
about what it is.
I want #'F to be a reference in the function namespace just as
plain F is a reference in the value namespace.
Consider the following in Scheme:
(let ((f (lambda ...)))
(eq f f))
This will return true. In Common Lisp, I might write it as:
(let ((f #'(lambda ...)))
(eq f f))
but I might prefer:
(flet ((f ...)) (eq #'f #'f))
I do not think that this additional transformation (into FLET) should
introduce any new uncertainty w.r.t. EQ -- because #'F, like F, is
just a reference (whose value has already been evaluated). The
relevance of the LET example is that it and the FLET version should
(in my view) be equivalent.
Put another way, I suggest that FUNCTION should be interpeted as
more or less a syntactic marker as in
<form> ::= ... | (FUNCTION <function>) | ...
<function> ::= <identifier> | (LAMBDA <lambda list> <form>*)
That is, (LAMBDA ...) in, say, ((LAMBDA ...) ...) has as its value
a function; (LAMBDA ...) in (FUNCTION (LAMBDA ...)) is interpreted
in more or less the same way; but in (... (LAMBDA ...) ...) it is not
[it's interpreted as a call to the (non-)function LAMBDA]. So in
the <identifier> case, FUNCTION simply indicates that the identifier
is a function name, not a variable.
In other words, I do not think of FUNCTION as an operation that
constructs a value -- it's not like LIST or MAKE-SYMBOL. Furthermore,
I am not saying that Common Lisp currently treats FUNCTION in the way
I prefer -- I am saying that (in my opinion) it should.
Finally, recent messages have shown that the "may make a new object
each time" view of (FUNCTION <identifier>) provides some freedom that
can be exploited in various ways. Whether this freedom is important
enough to determine the semantics is less clear.
I hope everyone isn't *too* tired of this.
Cheers,
Jeff
∂16-Sep-88 1324 Common-Lisp-mailer Common Lisp: The Reference
Received: from tut.cis.ohio-state.edu by SAIL.Stanford.EDU with TCP; 16 Sep 88 13:24:35 PDT
Received: by tut.cis.ohio-state.edu (5.54/2.880913)
id AA06515; Fri, 16 Sep 88 16:23:22 EDT
Date: Fri, 16 Sep 88 16:23:22 EDT
From: welch@tut.cis.ohio-state.edu (Arun Welch)
Message-Id: <8809162023.AA06515@tut.cis.ohio-state.edu>
To: common-lisp@sail.stanford.edu
Subject: Common Lisp: The Reference
I just got a flyer from Franz about this book. Has anyone else seen
it? Comments? Would you rate it a must-have, usefull,
something-to-put-on-the-shelf, or avoid-at-all-costs?
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
∂16-Sep-88 1449 Common-Lisp-mailer (eq #'eq #'eq) (reply to Jeff Dalton)
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 16 Sep 88 14:49:38 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa20129; 16 Sep 88 15:01 EDT
Received: from draper.com by RELAY.CS.NET id aa20297; 16 Sep 88 14:50 EDT
Date: Fri, 16 Sep 88 14:07 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: (eq #'eq #'eq) (reply to Jeff Dalton)
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
If SYMBOL-FUNCTION "returns the autoloader function", then (eq f #'eq)
...actually, this works out, but very peculiarly.
If EQ hasn't been autoloaded yet, and #'eq returns the eq-autoloader,
then f cannot be #'eq because the act of binding f to #'eq would have
invoked the autoloader to load the real #'eq. On the other hand, if
f IS #'eq, then f must be EQ to #'eq because #'eq will necessarily
return the already-autoloaded-by-binding-f #'eq. Simple, no?
I still don't consider this fortuitous setup to justify your point,
though. Autoloading isn't the only rationale in any case. COnsider
a system with multiple copies of the same function (perhaps liked into
several modules, or compiler-generated as quasi-inline minisubrs, or
whatever).
∂17-Sep-88 0856 Common-Lisp-mailer Re: (eq #'eq #'eq) (reply to Jeff Dalton)
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 17 Sep 88 08:54:25 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03792; 17 Sep 88 16:07 BST
Date: Sat, 17 Sep 88 16:41:31 BST
Message-Id: <2299.8809171541@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: (eq #'eq #'eq) (reply to Jeff Dalton)
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Fri, 16 Sep 88 14:07 EDT
Cc:
> If SYMBOL-FUNCTION "returns the autoloader function", then (eq f #'eq)
> ...actually, this works out, but very peculiarly.
It is not even slightly peculiar. (SYMBOL-FUNCTION 'F) returns
whatever it returns. Presumably it does this consistently. There are
two main cases: (1) F does not need to be autoloaded, and (2) F does
need to be loaded. The second case then has two subcases: (2a)
SYMBOL-FUNCTION causes the autoload to happen, or else (2b) it returns
the autoloader function.
Suppose F does not need to be autoloaded. Then SYMBOL-FUNCTION
returns the function value of F. If you call it again, it returns
that very same object (the function value) again. So these two
results are F. Now suppose F needs to be autoloaded. Either
calling SYMBOL-FUNCTION on F causes the autoloading to take place,
and we are in the same situation as above, or else it does not cause
the autoloading to take place but instead returns a function object
that, if called, will autoload F. Again, if you call SYMBOL-FUNCTION
again it will presumably behave in the same way and return the very
same <call me and I'll autoload F> function object. Again the
results are EQ.
Since this argument is independent of choice of F, it applies when
F is the symbol EQ.
> I still don't consider this fortuitous setup to justify your point,
> though.
It is not a fortuitous setup. Access functions (such as SYMBOL-
FUNCTION) return objects. Object identity can be tested with EQ.
Of course, you might say that SYMBOL-FUNCTION isn't a simple access
function. Perhaps it's not like SYMBOL-VALUE at all. Perhaps it
always makes a new function object. If we take this line, then I
am saying that SYMBOL-FUNCTION should change to be like SYMBOL-
VALUE. Again, this is neither peciliar nor fortuitous: it is just
a question of how SYMBOL-FUNCTION should behave.
> Autoloading isn't the only rationale in any case. Consider
> a system with multiple copies of the same function (perhaps liked into
> several modules, or compiler-generated as quasi-inline minisubrs, or
> whatever).
I don't really know what you have in mind here, so I'm probably going
to miss the point. I don't, for example, know what you mean by "the
same". If "same" means EQ, then they aren't copies. And I'm talking
only of #'F. This has different from cases like (F...), where F
might be compiled in-line.
-- Jeff
∂19-Sep-88 0626 Common-Lisp-mailer Multiple copies of functions
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 19 Sep 88 06:26:35 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa27067; 19 Sep 88 9:06 EDT
Received: from draper.com by RELAY.CS.NET id ab11298; 19 Sep 88 8:54 EDT
Date: Mon, 19 Sep 88 07:52 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: Multiple copies of functions
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
Consider DEFSTRUCT. DEFSTRUCT creates functions like make-foo, foo-slot,
foo-p, etc., etc.
These are mandated to be functions, although they used to be created as
macros in earlier Lisps. To retain efficiency, a compiler will probably
want to compile them as inline structure-accessors and the like, as if
they really were macros. The only case where you really need the body
of a function sitting around for them is in references like #'foo-slot.
In that case, it probably makes sense for the compiler to generate code
for foo-slot iff there is a #'foo-slot reference. Since these functions
are built by the expansion of DEFSTRUCT, rather than living in some
permanent place, and they may be created only when needed (even if not,
they still have to get created), it is possible for the compilation of
wholly separate pieces of code to need the "same" function (and you
would agree that they are the "same", would you not?). In such a case,
the function body referenced by #'foo-slot in one program may be at a
different virtual address from the function body referenced by another.
Maybe this wouldn't be sufficiently "same" for a number of reasons.
But I think that one could, if one put one's mind to it, come up with
some situation where there are two copies of the "same" function that
reside at different memory locations (invalidating EQ as a comparison),
yet for all intents and purposes are the "same" code.
I'd be happy to drop this topic. I think I've learned a lot about the
possible approaches to the problem, and I don't want to descend into
an operating-system-dependent mode.
∂19-Sep-88 1013 Common-Lisp-mailer Re: Multiple copies of functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 19 Sep 88 10:08:45 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04662; 19 Sep 88 17:12 BST
Date: Mon, 19 Sep 88 17:46:59 BST
Message-Id: <3978.8809191646@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Multiple copies of functions
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Mon, 19 Sep 88 07:52 EDT
Cc:
> Consider DEFSTRUCT. DEFSTRUCT creates functions like make-foo, foo-slot,
> foo-p, etc., etc.
Summary: they are no different from DEFUN'd functions except that they
tend to get compiled in-line.
> These are mandated to be functions, although they used to be created as
> macros in earlier Lisps. To retain efficiency, a compiler will probably
> want to compile them as inline structure-accessors and the like, as if
> they really were macros. The only case where you really need the body
> of a function sitting around for them is in references like #'foo-slot.
Or if I proclaim them NOTINLINE. In fact, as far as I know, nothing in
CLtL prevents the in-line compilation of *any* function provided it is
not declared NOTINLINE.
> In that case, it probably makes sense for the compiler to generate code
> for foo-slot iff there is a #'foo-slot reference. Since these functions
> are built by the expansion of DEFSTRUCT, rather than living in some
> permanent place, and they may be created only when needed (even if not,
> they still have to get created),
Um, functions are normally built by the expansion of the DEFUN macro,
so I don't see that DEFSTRUCT is so different from the normal case.
DEFUN'd functions could also not be created unless needed. Of course,
given that the DEFUN (or the DEFSTRUCT) might be in one file and the
call to it in another, the function probably will be attached to the
name in any case. And once it is, Lisp may as well return THAT
FUNCTION instead of creating a new one.
> it is possible for the compilation of
> wholly separate pieces of code to need the "same" function (and you
> would agree that they are the "same", would you not?). In such a case,
> the function body referenced by #'foo-slot in one program may be at a
> different virtual address from the function body referenced by another.
The address may be different for different in-line compilations, but
I don't see any point in having FUNCTION and hence SYMBOL-FUNCTION
build functions from different blocks of compiled code depending on
where they're called. And how about when I do something like
(funcall some-function 'f)
SOME-FUNCTION might turn out to be SYMBOL-FUNCTION. I suppose
SYMBOL-FUNCTION might (and still be valid Common Lisp) compile the
source code and return a new function each time, or something of that
sort, but my point is simply that there's no good reason to do so.
So, I don't see why Common Lisp should allow this freedom. (Well,
one reason has been suggested -- from InterLisp -- but I don't
think your new reason is sufficiently convincing.)
> Maybe this wouldn't be sufficiently "same" for a number of reasons.
> But I think that one could, if one put one's mind to it, come up with
> some situation where there are two copies of the "same" function that
> reside at different memory locations (invalidating EQ as a comparison),
> yet for all intents and purposes are the "same" code.
There would be two copies of the same if they're compiled in-line.
Otherwise, I don't see why one would want to do this.
I don't want EQ to tell me if two functions are the "same function";
I want it to tell me whether two objects that are both functions are
the same identical object; and EQ does do this. The remaining
question is whether (FUNCTION <symbol>) should create a new function
or simply return one. Neither decision for FUNCTION invalidates EQ
as a comparison for identity of function objects.
Again, I suspect we are really interested in different questions.
> I'd be happy to drop this topic. I think I've learned a lot about the
> possible approaches to the problem, and I don't want to descend into
> an operating-system-dependent mode.
Well, nothing that is operating-system dependent has yet come up,
so I suppose we can still stop in time.
Cheers,
Jeff
∂20-Sep-88 0202 Common-Lisp-mailer Re: Multiple copies of functions
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 20 Sep 88 02:02:40 PDT
Received: from Cabernet.ms by ArpaGateway.ms ; 20 SEP 88 02:01:19 PDT
Date: 20 Sep 88 02:01 PDT
From: masinter.pa@Xerox.COM
Subject: Re: Multiple copies of functions
To: jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK
cc: common-lisp@sail.stanford.edu
Message-ID: <880920-020119-3367@Xerox>
I think it is reasonable to allow #'FOO to allocate new structure, and also to
require that SYMBOL-FUNCTION does not.
I think it would be unfortunate to extend the loophole in EQ-referential
transparency currently allowed to numbers and characters to other data types,
especially since EQL-transparency still holds.
The invariant in question is:
(EQL X (PROGN (SETF <place> X) <place>) )
for side-effect free <place> (when legal, e.g., that <place> admits to 'holding'
X.) Allowing SYMBOL-FUNCTION to allocate new structure that is not
EQL-equivalent would make this fail for X = #'FOO and <place> = (SYMBOL-FUNCTION
y).
Also, for side-effect free generalized variable <place>, it is generally true
that (EQL <place> <place>).
However #'FOO is not a generalized variable, and #' is not an accessor, despite
its similarity to '.
Some possibilities
* require that (EQ (SYMBOL-FUNCTION 'FOO) (SYMBOL-FUNCTION 'FOO))
* require that they be EQL. This is slightly less burdensome on implementations
where they are in fact not EQ.
I think we can still allow implementations to create new (non-EQL) structure for
#'FOO even when the lexical environment might be null, since it doesn't violate
any other invariants.
- - - -
Re: NOTINLINE: the presumption in at least a couple of cleanup items has been
that by default user-DEFUNed functions are NOTINLINE and Common Lisp functions
are presumed to be potentially INLINE. Would you change these defaults?
∂20-Sep-88 0841 Common-Lisp-mailer Re: Multiple copies of functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 20 Sep 88 08:35:01 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04662; 19 Sep 88 17:12 BST
Date: Mon, 19 Sep 88 17:46:59 BST
Message-Id: <3978.8809191646@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Multiple copies of functions
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Mon, 19 Sep 88 07:52 EDT
Cc:
> Consider DEFSTRUCT. DEFSTRUCT creates functions like make-foo, foo-slot,
> foo-p, etc., etc.
Summary: they are no different from DEFUN'd functions except that they
tend to get compiled in-line.
> These are mandated to be functions, although they used to be created as
> macros in earlier Lisps. To retain efficiency, a compiler will probably
> want to compile them as inline structure-accessors and the like, as if
> they really were macros. The only case where you really need the body
> of a function sitting around for them is in references like #'foo-slot.
Or if I proclaim them NOTINLINE. In fact, as far as I know, nothing in
CLtL prevents the in-line compilation of *any* function provided it is
not declared NOTINLINE.
> In that case, it probably makes sense for the compiler to generate code
> for foo-slot iff there is a #'foo-slot reference. Since these functions
> are built by the expansion of DEFSTRUCT, rather than living in some
> permanent place, and they may be created only when needed (even if not,
> they still have to get created),
Um, functions are normally built by the expansion of the DEFUN macro,
so I don't see that DEFSTRUCT is so different from the normal case.
DEFUN'd functions could also not be created unless needed. Of course,
given that the DEFUN (or the DEFSTRUCT) might be in one file and the
call to it in another, the function probably will be attached to the
name in any case. And once it is, Lisp may as well return THAT
FUNCTION instead of creating a new one.
> it is possible for the compilation of
> wholly separate pieces of code to need the "same" function (and you
> would agree that they are the "same", would you not?). In such a case,
> the function body referenced by #'foo-slot in one program may be at a
> different virtual address from the function body referenced by another.
The address may be different for different in-line compilations, but
I don't see any point in having FUNCTION and hence SYMBOL-FUNCTION
build functions from different blocks of compiled code depending on
where they're called. And how about when I do something like
(funcall some-function 'f)
SOME-FUNCTION might turn out to be SYMBOL-FUNCTION. I suppose
SYMBOL-FUNCTION might (and still be valid Common Lisp) compile the
source code and return a new function each time, or something of that
sort, but my point is simply that there's no good reason to do so.
So, I don't see why Common Lisp should allow this freedom. (Well,
one reason has been suggested -- from InterLisp -- but I don't
think your new reason is sufficiently convincing.)
> Maybe this wouldn't be sufficiently "same" for a number of reasons.
> But I think that one could, if one put one's mind to it, come up with
> some situation where there are two copies of the "same" function that
> reside at different memory locations (invalidating EQ as a comparison),
> yet for all intents and purposes are the "same" code.
There would be two copies of the same if they're compiled in-line.
Otherwise, I don't see why one would want to do this.
I don't want EQ to tell me if two functions are the "same function";
I want it to tell me whether two objects that are both functions are
the same identical object; and EQ does do this. The remaining
question is whether (FUNCTION <symbol>) should create a new function
or simply return one. Neither decision for FUNCTION invalidates EQ
as a comparison for identity of function objects.
Again, I suspect we are really interested in different questions.
> I'd be happy to drop this topic. I think I've learned a lot about the
> possible approaches to the problem, and I don't want to descend into
> an operating-system-dependent mode.
Well, nothing that is operating-system dependent has yet come up,
so I suppose we can still stop in time.
Cheers,
Jeff
∂20-Sep-88 1505 Common-Lisp-mailer Re: Multiple copies of functions
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 20 Sep 88 15:02:03 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04662; 19 Sep 88 17:12 BST
Date: Mon, 19 Sep 88 17:46:59 BST
Message-Id: <3978.8809191646@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Multiple copies of functions
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Mon, 19 Sep 88 07:52 EDT
Cc:
> Consider DEFSTRUCT. DEFSTRUCT creates functions like make-foo, foo-slot,
> foo-p, etc., etc.
Summary: they are no different from DEFUN'd functions except that they
tend to get compiled in-line.
> These are mandated to be functions, although they used to be created as
> macros in earlier Lisps. To retain efficiency, a compiler will probably
> want to compile them as inline structure-accessors and the like, as if
> they really were macros. The only case where you really need the body
> of a function sitting around for them is in references like #'foo-slot.
Or if I proclaim them NOTINLINE. In fact, as far as I know, nothing in
CLtL prevents the in-line compilation of *any* function provided it is
not declared NOTINLINE.
> In that case, it probably makes sense for the compiler to generate code
> for foo-slot iff there is a #'foo-slot reference. Since these functions
> are built by the expansion of DEFSTRUCT, rather than living in some
> permanent place, and they may be created only when needed (even if not,
> they still have to get created),
Um, functions are normally built by the expansion of the DEFUN macro,
so I don't see that DEFSTRUCT is so different from the normal case.
DEFUN'd functions could also not be created unless needed. Of course,
given that the DEFUN (or the DEFSTRUCT) might be in one file and the
call to it in another, the function probably will be attached to the
name in any case. And once it is, Lisp may as well return THAT
FUNCTION instead of creating a new one.
> it is possible for the compilation of
> wholly separate pieces of code to need the "same" function (and you
> would agree that they are the "same", would you not?). In such a case,
> the function body referenced by #'foo-slot in one program may be at a
> different virtual address from the function body referenced by another.
The address may be different for different in-line compilations, but
I don't see any point in having FUNCTION and hence SYMBOL-FUNCTION
build functions from different blocks of compiled code depending on
where they're called. And how about when I do something like
(funcall some-function 'f)
SOME-FUNCTION might turn out to be SYMBOL-FUNCTION. I suppose
SYMBOL-FUNCTION might (and still be valid Common Lisp) compile the
source code and return a new function each time, or something of that
sort, but my point is simply that there's no good reason to do so.
So, I don't see why Common Lisp should allow this freedom. (Well,
one reason has been suggested -- from InterLisp -- but I don't
think your new reason is sufficiently convincing.)
> Maybe this wouldn't be sufficiently "same" for a number of reasons.
> But I think that one could, if one put one's mind to it, come up with
> some situation where there are two copies of the "same" function that
> reside at different memory locations (invalidating EQ as a comparison),
> yet for all intents and purposes are the "same" code.
There would be two copies of the same if they're compiled in-line.
Otherwise, I don't see why one would want to do this.
I don't want EQ to tell me if two functions are the "same function";
I want it to tell me whether two objects that are both functions are
the same identical object; and EQ does do this. The remaining
question is whether (FUNCTION <symbol>) should create a new function
or simply return one. Neither decision for FUNCTION invalidates EQ
as a comparison for identity of function objects.
Again, I suspect we are really interested in different questions.
> I'd be happy to drop this topic. I think I've learned a lot about the
> possible approaches to the problem, and I don't want to descend into
> an operating-system-dependent mode.
Well, nothing that is operating-system dependent has yet come up,
so I suppose we can still stop in time.
Cheers,
Jeff
∂21-Sep-88 0046 Common-Lisp-mailer (eq #'eq #'eq)
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 21 Sep 88 00:46:12 PDT
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA05204g; Tue, 20 Sep 88 23:44:33 PST
Received: by bhopal id AA21489g; Wed, 21 Sep 88 00:44:01 PDT
Date: Wed, 21 Sep 88 00:44:01 PDT
From: Jon L White <jonl@lucid.com>
Message-Id: <8809210744.AA21489@bhopal>
To: SEB1525@draper.com
Cc: common-lisp@SAIL.STANFORD.EDU
In-Reply-To: "Steve Bacher (Batchman)"'s message of Thu, 15 Sep 88 07:26 EDT <8809151609.AA01072@lucid.com>
Subject: (eq #'eq #'eq)
re: I was pleased to hear that it is conceivable for a valid CL
implementation not necessarily to return the same object for
(SYMBOL-FUNCTION foo) all the time. Such freedom is probably
necessary in order to support function autoloading on (formerly
much-maligned until recent developments in the business world)
"stock hardware".
Lucid's releae 3.0 contains a simple but effective "autoload" scheme.
The issue of whether SYMBOL-FUNCTION and MACRO-FUNCTION should load-in
an autoloadable function was raised during design deliberations, but no
satisfactory resolution was obtained. As a compromise, there is a
function ENSURE-AUTOLOADED to "snap it in" if it isn't already loaded.
-- JonL --
∂21-Sep-88 1731 Common-Lisp-mailer KCL (or AKCL) on the Sequent?
Received: from gateway.mitre.org by SAIL.Stanford.EDU with TCP; 21 Sep 88 17:30:54 PDT
Received: by gateway.mitre.org (5.54/SMI-2.2)
id AA07078; Wed, 21 Sep 88 17:24:51 EDT
Return-Path: <howell%community-chest.mitre.org@gateway.mitre.org>
Received: from localhost by baltic.mitre.org (3.2/SMI-2.2)
id AA05633; Wed, 21 Sep 88 17:27:12 EDT
Message-Id: <8809212127.AA05633@baltic.mitre.org>
To: common-lisp@sail.stanford.edu, kcl@cli.com
Cc: howell@mitre.ARPA
Subject: KCL (or AKCL) on the Sequent?
Date: Wed, 21 Sep 88 17:27:08 -0400
From: howell%community-chest.mitre.org@gateway.mitre.org
Has anyone put KCL on the Sequent Balance 8000? If so, any major
gotcha's, or is it painless?
Thanks,
Chuck Howell
The MITRE Corporation, Mail Stop Z645
7525 Colshire Drive, McLean, VA 22102
NET: howell@mitre.arpa or
howell%community-chest.mitre.org@gateway.mitre.org
∂22-Sep-88 1401 Common-Lisp-mailer (eq #'f #'f) and :TEMPORARY hash tables
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 22 Sep 88 14:01:03 PDT
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA06800g; Thu, 22 Sep 88 12:56:08 PST
Received: by bhopal id AA06559g; Thu, 22 Sep 88 13:55:36 PDT
Date: Thu, 22 Sep 88 13:55:36 PDT
From: Jon L White <jonl@lucid.com>
Message-Id: <8809222055.AA06559@bhopal>
To: Moon@STONY-BROOK.SCRC.Symbolics.COM
Cc: barmar@Think.COM, SEB1525@draper.com, common-lisp@sail.stanford.edu,
jeff@aiai.edinburgh.ac.uk
In-Reply-To: David A. Moon's message of Thu, 15 Sep 88 13:36 EDT <19880915173625.6.MOON@EUPHRATES.SCRC.Symbolics.COM>
Subject: (eq #'f #'f) and :TEMPORARY hash tables
re: ... if equivalence of closures is something different from EQ, I have
trouble figuring out what it would be defined as that would have any
meaning that was both portable and effectively computable.
There is a rather simple equivalence used internally in Lucid Common
Lisp -- not unlike extending EQUAL to pointer vectors -- by recursive
descent into the "components" (of course, just what the "components" of
a function/closure are is an implementation dependent issue). It is
used during a "coalescing" phase, when functions can be made read-only.
However, in terms of the (eq #'f #'f) issue, the way in which EQL could
reasonably differ from EQ is the same way in which it does so in
Interlisp-D -- namely, evaluating (FUNCTION F) is not merely a field
access into a symbol structure, but rather the consing up of a trivially
small structure that holds normal pointers for the components of the "real"
function named by F. Because of the lower-level internals, it wasn't
convenient for Interlisp-D to retain, for example, the address of the
function's code as a first-class pointer; so evaluating #'F would
simply normalize the internal bits, and return them in a freshly-cons'd
up structure. For "functions" x and y, (EQP x y) is more or less like
(and (eq (component-1 x) (component-1 x))
(eq (component-2 x) (component-2 x))
...)
[but not every conceivable component is included in this compound test.]
-- JonL --
P.S. I'm not really serious about extending EQL to act like Interlisp's
EQP on functions. The original motivation for this discussion was
the characterization of hash-table equivalence predicates; and
certainly, means other than the temporal value of #'f can be used
to identify the test. To my knowledge, only Symbolics and Lucid have
any hooks for permitting random :test functions to be used in hash
tables (Lucid's facilities are not "exported" to the end customer),
and neither of these implementations has the EQ/EQP difficulty on
global functions.
∂22-Sep-88 1558 Common-Lisp-mailer :TEMPORARY hash tables; weak pointers
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 22 Sep 88 15:58:18 PDT
Received: from snail.sun.com by Sun.COM (4.0/SMI-4.0)
id AA28916; Thu, 22 Sep 88 15:54:47 PDT
Received: from lukasiewicz.sun.com by snail.sun.com (4.0/SMI-4.0)
id AA19622; Thu, 22 Sep 88 15:57:33 PDT
Received: by lukasiewicz.sun.com (4.0/SMI-4.0)
id AA17839; Thu, 22 Sep 88 14:50:59 PDT
Date: Thu, 22 Sep 88 14:50:59 PDT
From: jrose@Sun.COM (John Rose)
Message-Id: <8809222150.AA17839@lukasiewicz.sun.com>
To: common-lisp@sail.stanford.edu
Cc: jonl@lucid.com, Moon@STONY-BROOK.SCRC.Symbolics.COM, barmar@Think.COM,
SEB1525@draper.com, peck@denali jeff@aiai.edinburgh.ac.uk
In-Reply-To: Jon L White's message of Thu, 22 Sep 88 13:55:36 PDT <8809222055.AA06559@bhopal>
Subject: :TEMPORARY hash tables; weak pointers
As long as we're still talking about weak pointers and related topics,
I should note that there seem to be two very different broad categories
of weak pointer usage. (If you know a third, please speak up.)
1. Hash Consing
This kind of usage has been mentioned on this mailing list already.
The idea is that you need to add a slot to an object, but you don't
have control over the object's memory layout. For example, CLOS
defines SYMBOL-CLASS as a SETF-able location for each symbol;
it behaves much like SYMBOL-NAME, SYMBOL-VALUE, etc. (For most symbols,
the slot is unbound.) Although SYMBOL-CLASS behaves semantically
just like a new slot in the per-symbol data structure, it is
almost certainly implemented differently than SYMBOL-VALUE.
Instead, the slot is often stored in a hash table, whose
keys are symbol addresses, and values are SYMBOL-CLASS
places. This technique is general: If there's no room
for an attribute in a data structure's contiguous block of memory,
allocate more space for the attribute somewhere else, and
record the new location in a hash table keyed by the old
location.
This technique requires weak pointers in the hash table keys.
Suppose a symbol is no longer used, and should be GC-able.
There is still a problem if the symbol has any hash-consed
slots (like SYMBOL-CLASS), since some hash table somewhere
records it as a key, and may thus prevent deletion of the
symbol.
It is clear that (:TEMPORARY T :TEST 'EQ) hash tables would
be well suited for hash consing.
2. Back Pointers
A completely different use of weak pointers, which I don't
recall seeing mentioned here recently, involves data structures
with back pointers. In general, when a single central object
is referenced by many dependent objects, it is sometimes
necessary for the central object to have a list of back
pointers to the dependents.
The classic example has to do with text editor marks. A "mark"
is a little pointer which records a position between two
characters in a string being edited. Marks are more
interesting than simple integer positions, because they float:
If the first half of a string is deleted, all the marks into
the second half must continue to point at the same characters.
In practice, marks are ordered pairs of integers and strings,
so when the underlying string is shifted somehow, the editor
must be sure to visit all marks on that string, and update
their integer components. This requires maintenance of
pointers which invert the mark-to-string relationship,
and the back pointers are in fact sets of pointers, since
string-to-mark is a one-to-many relationship.
The problem here is that marks are often consed and discarded
at a great rate. But if a mark's back pointer is not
explicitly cleared, the string's reference to the mark will
keep the mark from being GC-ed. The result is a performance
degradation, since the string is burdened with longer and
longer lists of useless marks to keep updated.
One thing that would help here is a "weak set" construct,
which would hold all of the back pointers. The weak set
would support looping over its members, but would not
prevent reclamation of garbage objects.
You can build a weak set out of a (:TEMPORARY T :TEST 'EQ) hash
table by storing the back pointers as keys. The values stored
on the keys are immaterial; T would do fine! The only use of
GETHASH would be to SETF in new back pointers; the MAPHASH
function would perform the looping function.
I'm not completely comfortable with using hash tables this way;
it seems as waste of half of the hash table functionality.
Perhaps intellectual integrity requires a separate notion of
weak set? I believe the following intriguing hash table extension
lets us keep our integrity, without introducing weak sets per se:
(MAKE-HASH-TABLE &KEY ... (TYPE T) ...)
The new keyword :TYPE declares the type of all values to be stored
in the hash table. Certain implementations may be able to optimize
the storage of numeric, character, or boolean types. In addition, if
TYPE is a singleton (e.g., NULL or (MEMBER T)), certain
implementations may be able to use a significantly more efficient
representation.
So:
(defun make-weak-set () (make-hash-table :temporary t :type 'null))
(defun weak-set-adjoin (x s) (setf (gethash x s) nil) s)
(defun weak-set-delete (x s) (remhash x s) s)
(defun weak-set-member (x s) (not (gethash x s t)))
(defun map-weak-set (f s) (maphash #'(lambda (k v) v (funcall f k)) s))
(What about declaring key types too? Well, that's another story.
Note the key type is closely tied to the choices of test and
hash functions.)
So, those are the uses of weak pointers I know about. What
else is there?
(Hope this doesn't beat the issue to death...)
-- John
∂23-Sep-88 0455 Common-Lisp-mailer
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 23 Sep 88 04:54:32 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03728; 23 Sep 88 11:59 BST
Date: Fri, 23 Sep 88 12:36:11 BST
Message-Id: <12271.8809231136@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
To: John Rose <jrose@sun.com>, common-lisp@sail.stanford.edu
Cc: jonl <@sail.stanford.edu:jonl@lucid.com>, Moon@scrc-stony-brook.arpa,
barmar@think.com,
SEB1525 <@NSS.Cs.Ucl.AC.UK,@sail.standfor.edu:SEB1525@draper.com>
> As long as we're still talking about weak pointers and related topics,
> I should note that there seem to be two very different broad categories
> of weak pointer usage. (If you know a third, please speak up.)
>
> 1. Hash Consing
> This kind of usage has been mentioned on this mailing list already.
> The idea is that you need to add a slot to an object, but you don't
> have control over the object's memory layout.
> 2. Back Pointers
> One thing that would help here is a "weak set" construct,
>
> You can build a weak set out of a (:TEMPORARY T :TEST 'EQ) hash
> table by storing the back pointers as keys. The values stored
> on the keys are immaterial; T would do fine!
I did mention this in one of the earlier messages because I wanted
T's weak sets to count as part of "current practice". Since
an implementation using hash tables does waste 1/2 of each entry,
you're type suggestion seems reasonable. (Quick look at arrays
in CLtL...) Indeed, array element types are also specified by a
keyword parameter so there is precedent for that approach.
There should probably be a type parameter for the key as well.
So we'd have :KEY-TYPE and :VALUE-TYPE.
-- Jeff
∂23-Sep-88 0655 Common-Lisp-mailer (eq #'eq #'eq)
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 23 Sep 88 06:54:56 PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa06508; 23 Sep 88 9:09 EDT
Received: from cs.umass.edu by RELAY.CS.NET id dl16422; 23 Sep 88 8:55 EDT
Date: Wed, 21 Sep 88 10:21 EDT
From: ELIOT@cs.umass.edu
Subject: (eq #'eq #'eq)
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: in%"common-lisp@sail.stanford.EDU"
If you really wanted functions to be EQ to themselves in all
"reasonable" cases, even autoloading need not interfere. Th
autoload definition could be newly CONSed for each function, and
when the real definition is actually loaded it should not be stored
normally, but stuffed inside the original autoload function, presumably
linked with a BRANCH instruction. This would add one short instruction
of overhead, and make inspection/disassembly/debugging harder, but
at least it shows that the physical address of a function does not
have to change because of autoloading.
Chris Eliot
Umass Amherst
∂23-Sep-88 0709 Common-Lisp-mailer Re: (eq #'f #'f) and :TEMPORARY hash tables
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 23 Sep 88 07:08:15 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04427; 23 Sep 88 14:24 BST
Date: Fri, 23 Sep 88 15:01:02 BST
Message-Id: <12791.8809231401@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: (eq #'f #'f) and :TEMPORARY hash tables
To: Jon L White <@sail.stanford.edu:jonl@lucid.com>
In-Reply-To: Jon L White's message of Thu, 22 Sep 88 13:55:36 PDT
Cc: barmar@think.com, SEB1525 <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
> To my knowledge, only Symbolics and Lucid have any hooks for
> permitting random :test functions to be used in hash tables
> (Lucid's facilities are not "exported" to the end customer),
> and neither of these implementations has the EQ/EQP difficulty
> on global functions.
Pop11's properties (hash tables to us) allow the user to specify
a predicate and a hash function. It also (to judge from PopLog
Common Lisp) lacks the EQ/EQP difficulty.
-- Jeff
∂23-Sep-88 1006 Common-Lisp-mailer Re: Hash tables and GC
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 23 Sep 88 10:05:04 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05473; 23 Sep 88 17:18 BST
Date: Fri, 23 Sep 88 17:55:41 BST
Message-Id: <13592.8809231655@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: Hash tables and GC
To: common-lisp@sail.stanford.edu
I was just looking through the LISP/VM documentation and found another
bit of current practice. MAKE-HASH-TABLE takes an argument that is
either WEAK or STRONG (default STRONG). For weak tables, entries are
removed if there are no other pointers to the key.
∂23-Sep-88 1039 Common-Lisp-mailer (eq #'f #'f) and :TEMPORARY hash tables
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 23 Sep 88 10:39:44 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab06923; 23 Sep 88 9:42 EDT
Received: from draper.com by RELAY.CS.NET id aa16699; 23 Sep 88 9:34 EDT
Date: Fri, 23 Sep 88 07:28 EDT
From: "Steve Bacher (Batchman)" <SEB1525@draper.com>
Subject: (eq #'f #'f) and :TEMPORARY hash tables
To: common-lisp@SAIL.STANFORD.EDU
X-VMS-To: COMMON-LISP,SEB1525
After all the dust has cleared, it seems that you don't need to use
SYMBOL-FUNCTION at all to test function equality in make-hash-table or
similar functions. So it doesn't matter whether SYMBOL-FUNCTION is a
plain accessor or not. FUNCTION, however, tends to be NOT a plain accessor.
So the predicate passed to make-hash-table will have already been built by
the caller having issued FUNCTION, and probably the most appropriate way to
code the thing (assuming an Interlisp EQP function or something like it)
would be:
(if (eqp test '#,#'eq) (blah blah blah ...))
∂26-Sep-88 1022 Common-Lisp-mailer I'd like to be removed from the common lisp mailing list
Received: from RELAY.CS.NET by SAIL.Stanford.EDU with TCP; 26 Sep 88 10:22:42 PDT
Received: from relay2.cs.net by RELAY.CS.NET id ab12160; 25 Sep 88 20:51 EDT
Received: from cgi.com by RELAY.CS.NET id aa03826; 25 Sep 88 20:41 EDT
Date: Sun, 25 Sep 88 19:44 EST
From: DAVID HORNIG <HORNIG@cgi.com>
To: common-lisp@SAIL.STANFORD.EDU
Subject: I'd like to be removed from the common lisp mailing list
X-VMS-To: IN%"common-lisp@sail.stanford.edu"
Could you do that, or tell me how to do it? Thanks.
∂26-Sep-88 1030 Common-Lisp-mailer
Received: from AI.AI.MIT.EDU by SAIL.Stanford.EDU with TCP; 26 Sep 88 10:30:36 PDT
Date: Mon, 26 Sep 88 04:58:03 EDT
From: "Robert W. Kerns" <RWK@AI.AI.MIT.EDU>
To: Common-Lisp@SAIL.STANFORD.EDU
In-reply-to: Msg of Thu 22 Sep 88 14:50:59 PDT from jrose at Sun.COM (John Rose)
In-reply-to: Msg of Fri 23 Sep 88 00:22:57 EDT from Communications Satellite <COMSAT at AI.AI.MIT.EDU>
Message-ID: <450805.880926.RWK@AI.AI.MIT.EDU>
[Delayed because of a Babyl bug...]
The other way to generalize hash tables to allow for sets is in terms
of the number of values stored. If you Symbolics has a :NUMBER-OF-VALUES
argument, which can be 0 or 1. (It could be more, but this is made awkward
by the order of arguments to PUTHASH).
∂26-Sep-88 1043 Common-Lisp-mailer Re: (eq #'f #'f) and :TEMPORARY hash tables
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 26 Sep 88 10:42:22 PDT
Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa03415; 25 Sep 88 15:30 BST
Date: Sun, 25 Sep 88 16:08:10 BST
Message-Id: <16385.8809251508@subnode.aiai.ed.ac.uk>
From: Jeff Dalton <jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK>
Subject: Re: (eq #'f #'f) and :TEMPORARY hash tables
To: "Steve Bacher (Batchman)" <@sail.stanford.edu:SEB1525@draper.com>,
common-lisp@sail.stanford.edu
In-Reply-To: Steve Bacher (Batchman)'s message of Fri, 23 Sep 88 07:28 EDT
Cc:
> After all the dust has cleared, it seems that you don't need to use
> SYMBOL-FUNCTION at all to test function equality in make-hash-table or
> similar functions.
I thought I wasn't going to send anything more on this topic, but I'm
puzzled as to why it was ever thought this was an issue. MAKE-HASH-
TABLE has to find out which :TEST it has if it wants to use a
different hash function in each case. Steve has pointed out that it
doesn't really have to do this. It could just call the :TEST to
compare objects and (presumably) not use different hashes. Well,
that's certainly true, because nothing in CLtL guarantees that it
can't secretly use alists and not hash at all.
Nonetheless, it has always been fairly clear that *whatever*
MAKE-HASH-TABLE does now will suffice for :TEMPORARY tables too.
Or, rather, for permitting the existence of temp tables.
If necessary, we can bring in the fact that :TEMPORARY tables can just
be ordinary tables, because we cannot specify when entries would
actually be removed in any case. Moreover, if it is an error for the
:TEST to be anything other than EQ, #'EQ, EQL, etc. we can tell which
it is by trying it on various objects that we construct for that
purpose. And, finally, there is EQP and the like (i.e., an internal
comaprison that checks whetehr functions are composed of the same
parts).
> So it doesn't matter whether SYMBOL-FUNCTION is a plain accessor
> or not.
It may not matter here, but it generally does matter when new objects
are created and when they are not.
> FUNCTION, however, tends to be NOT a plain accessor.
Actually, it tends TO be a plain accessor. The implementations in
which it is not are (as far as I can tell) a minority.
∂26-Sep-88 1206 Common-Lisp-mailer Seeking Linear Algebra and Optimization code.
Received: from po2.andrew.cmu.edu by SAIL.Stanford.EDU with TCP; 26 Sep 88 12:06:21 PDT
Received: by po2.andrew.cmu.edu (5.54/3.15) id <AA02741> for common-lisp@sail.stanford.edu; Mon, 26 Sep 88 15:04:26 EDT
Received: via switchmail; Mon, 26 Sep 88 15:04:17 -0400 (EDT)
Received: from unix0.andrew.cmu.edu via qmail
ID </afs/andrew.cmu.edu/service/mailqs/q004/QF.unix0.andrew.cmu.edu.233e9464.e9160>;
Mon, 26 Sep 88 15:03:02 -0400 (EDT)
Received: from unix0.andrew.cmu.edu via qmail
ID </afs/andrew.cmu.edu/usr24/mm8s/.Outgoing/QF.unix0.andrew.cmu.edu.233e9459.d6f1e7>;
Mon, 26 Sep 88 15:02:50 -0400 (EDT)
Received: from Version.6.20.N.CUILIB.3.44.SNAP.NOT.LINKED.unix0.andrew.cmu.edu.vax.22
via MS.5.5.unix0.andrew.cmu.edu.vax_22;
Mon, 26 Sep 88 15:02:47 -0400 (EDT)
Message-Id: <UXDdFL918k-0E1tl5R@andrew.cmu.edu>
Date: Mon, 26 Sep 88 15:02:47 -0400 (EDT)
From: Michael Meyer <mm8s+@andrew.cmu.edu>
X-Andrew-Message-Size: 335+0
To: bb-clisp@pt.cs.cmu.edu, common-lisp@sail.stanford.edu,
Outbound News <outnews+ext.nn.comp.lang.lisp@andrew.cmu.edu>
Subject: Seeking Linear Algebra and Optimization code.
Hello:
Does anyone have (or know of) and public domain common lisp code for numerical
linear algebra and/or numerical optimization. I'm looking for something along
the lines of (common lisp versions of) Linpack for Linear Algebra, and Minpack
for optimization.
Any pointers would be greatly appreciated.
Mike Meyer
Statistics, CMU.
∂26-Sep-88 1237 Common-Lisp-mailer COMPILER-LET
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 26 Sep 88 12:37:27 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA25080; Mon, 26 Sep 88 13:36:05 MDT
Received: by defun.utah.edu (5.54/utah-2.0-leaf)
id AA05384; Mon, 26 Sep 88 13:36:02 MDT
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8809261936.AA05384@defun.utah.edu>
Date: Mon, 26 Sep 88 13:36:01 MDT
Subject: COMPILER-LET
To: common-lisp@sail.stanford.edu
Cc: cl-compiler@sail.stanford.edu
The ANSI X3J13 (Common Lisp Standardization) compiler cleanup committee
is contemplating a proposal to remove COMPILER-LET from the language.
If you have some code that uses COMPILER-LET and you don't think that
it could be rewritten to use some other construct, the compiler
committee (cl-compiler@sail.stanford.edu) would like to hear about it.
Reasons for flushing COMPILER-LET include:
* COMPILER-LET is ugly and confusing. The dynamic extent of the variable
bindings in interpreted code can lead to subtle bugs. In compiled code,
the variable bindings are only visible to macros within the lexical scope
of the COMPILER-LET.
* COMPILER-LET appears to be rarely used.
* Most (all?) instances of using COMPILER-LET for the purpose suggested
in CLtL ("communication among complicated macros") can be handled
just as well using MACROLET. Using MACROLET for this purpose also makes
it more clear that the expansion of certain macros depends upon the
lexical context in which they appear.
For example, suppose I have something like:
(eval-when (eval compile)
(defvar *foo* nil))
(defmacro foo-macro (x)
(compute-foo-expansion x))
Then, I could replace
(compiler-let ((*foo* t))
... (foo-macro ...))
with
(macrolet ((foo-macro (x)
(let ((*foo* t))
(compute-foo-expansion x))))
... (foo-macro ...))
-Sandra Loosemore (sandra@cs.utah.edu)
-------
∂26-Sep-88 1413 Common-Lisp-mailer COMPILER-LET
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 26 Sep 88 14:12:56 PDT
Received: from GRYPHON.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 465834; Mon 26-Sep-88 17:11:24 EDT
Date: Mon, 26 Sep 88 17:11 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: COMPILER-LET
To: sandra%defun@cs.utah.edu
cc: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu
In-Reply-To: <8809261936.AA05384@defun.utah.edu>
Message-ID: <880926171117.9.KMP@GRYPHON.SCRC.Symbolics.COM>
Date: Mon, 26 Sep 88 13:36:01 MDT
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
... COMPILER-LET is ugly and confusing. The dynamic extent of the variable
bindings in interpreted code can lead to subtle bugs. In compiled code,
the variable bindings are only visible to macros within the lexical scope
of the COMPILER-LET. ...
The whole purpose of COMPILER-LET is to allow communication between textually
unrelated macros, so of course it's only visible within the lexical scope of
the COMPILER-LET in the compiler.
In my opinion, the real problem is that interpreted-only implementations are not
required to make a semantic-prepass. This means that macro expansion and
COMPILER-LET handling may happen all at once or at any known time, so it must
risk interfering with runtime variable bindings. If interpreters were required
to do the pre-pass (effectively, a mini-compile just doing macro expansion, etc),
not only would COMPILER-LET seem ok, but other problem spots in the language
(like EVAL-WHEN) would be easier to tackle as well.
I've sent more detailed comments to CL-Compiler, and will carry on a complete
technical discussion there, but I wanted to make this reply to all of Common-Lisp
since many people will not see that discussion so that they know that this is
not as one-sided an issue as you have painted it.
End of opposition viewpoint.
∂26-Sep-88 1502 Common-Lisp-mailer Re: COMPILER-LET
Received: from Score.Stanford.EDU by SAIL.Stanford.EDU with TCP; 26 Sep 88 15:02:06 PDT
Received: from hpfclp.sde.hp.com by SCORE.STANFORD.EDU with TCP; Mon 26 Sep 88 14:59:56-PDT
Received: by hpfclp.sde.hp.com; Mon, 26 Sep 88 16:00:10 mdt
Date: Mon, 26 Sep 88 16:00:10 mdt
From: John Diamant <diamant@hpfclp.sde.hp.com>
Full-Name: John Diamant
Message-Id: <8809262200.AA03819@hpfclp.sde.hp.com>
To: common-lisp@sail.stanford.edu
Subject: Re: COMPILER-LET
In-Reply-To: article <2430160@hpfclp.SDE.HP.COM> of Mon, 26 Sep 1988 20:16:37 GMT
> From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
> Reasons for flushing COMPILER-LET include:
>
> * COMPILER-LET is ugly and confusing. The dynamic extent of the variable
> bindings in interpreted code can lead to subtle bugs. In compiled code,
> the variable bindings are only visible to macros within the lexical scope
> of the COMPILER-LET.
In addition, both the original text in CLtL and this description make
assumptions about the evaluation strategy employed by the implementation (they
assume a conventional interpreter, which is explicitly not required by
CLtL. In a preprocessor or compile always implementation, this special
form and description make no sense at all. Flush it, and good riddance.
John Diamant
Software Development Environments
Hewlett-Packard Co. ARPA Internet: diamant@hpfclp.sde.hp.com
Fort Collins, CO UUCP: {hplabs,hpfcla}!hpfclp!diamant
∂27-Sep-88 1030 CL-Compiler-mailer Re: COMPILER-LET
Received: from gremlin.nrtc.northrop.com by SAIL.Stanford.EDU with TCP; 27 Sep 88 10:29:58 PDT
Received: from tribble by gremlin.nrtc.northrop.com id aa03839;
27 Sep 88 10:27 PDT
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu,
jbarnett@gremlin.nrtc.northrop.com
Subject: Re: COMPILER-LET
In-reply-to: Your message of Mon, 26 Sep 88 13:36:01 -0600.
<8809261936.AA05384@defun.utah.edu>
Date: Tue, 27 Sep 88 10:27:47 -0700
From: jbarnett@gremlin.nrtc.northrop.com
I want to reply to your comments that COMPILER-LET is (1) ugly and confusing,
(2) rarely used, and (3) can be replaced with MACRO-LET. The second point is
probably true. As to the other points I wish to disagree. As to the first
point: I was delighted to see COMPILER-LET in the language because it was the
obvious clean LISPish way to gain a lot of useful capability for compilers and
extentions layered on top of LISP.
The method that you showed of using MACRO-LET doesn't really work very well.
There is a strategy that will work but it is a real croc: A macro that was
going to output the COMPILER-LET wrapper outputs a MACRO-LET that includes a
local macro that produces the quoted of the value that would have been bound to
the special variable. A macro that wishes to consume that value must pass a
form like (LOCAL-MACRO-NAME) to EVAL along with an environment pointer.
∂27-Sep-88 1039 CL-Compiler-mailer Re: COMPILER-LET
Received: from gremlin.nrtc.northrop.com by SAIL.Stanford.EDU with TCP; 27 Sep 88 10:38:58 PDT
Received: from tribble by gremlin.nrtc.northrop.com id aa03860;
27 Sep 88 10:37 PDT
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu,
jbarnett@gremlin.nrtc.northrop.com
Subject: Re: COMPILER-LET
In-reply-to: Your message of Mon, 26 Sep 88 13:36:01 -0600.
<8809261936.AA05384@defun.utah.edu>
Date: Tue, 27 Sep 88 10:37:09 -0700
From: jbarnett@gremlin.nrtc.northrop.com
Sorry, the mailer and I weren't coordinated and the first half of this slipped
away.
The point of the first half is that if you wanted to COMPILER-LET several
variables that were consumed by the same macro, the combinatorics of your
solution would be bad news. Further, in your solution, the scope is wrong.
In general, COMPILER-LET and MACRO-LET, will appear semi-independently and if
both are used the nesting order is critical.
In any event, I hope that COMPILER-LET remains in the language. I have found it
an easy and natural construct to use for implementing various language
extentions. In addition, it seems that it should be trivial to make EVALed
forms enjoy the same semantics that the compiler proffers.
∂27-Sep-88 1221 CL-Compiler-mailer Re: COMPILER-LET
Received: from cs.utah.edu by SAIL.Stanford.EDU with TCP; 27 Sep 88 12:20:57 PDT
Received: by cs.utah.edu (5.54/utah-2.0-cs)
id AA17953; Tue, 27 Sep 88 13:19:31 MDT
Received: by defun.utah.edu (5.54/utah-2.0-leaf)
id AA06137; Tue, 27 Sep 88 13:19:22 MDT
From: sandra%defun@cs.utah.edu (Sandra J Loosemore)
Message-Id: <8809271919.AA06137@defun.utah.edu>
Date: Tue, 27 Sep 88 13:19:20 MDT
Subject: Re: COMPILER-LET
To: jbarnett@gremlin.nrtc.northrop.com
Cc: Sandra J Loosemore <sandra%defun@cs.utah.edu>,
common-lisp@sail.stanford.edu, cl-compiler@sail.stanford.edu,
jbarnett@gremlin.nrtc.northrop.com
In-Reply-To: jbarnett@gremlin.nrtc.northrop.com, Tue, 27 Sep 88 10:37:09 -0700
> Date: Tue, 27 Sep 88 10:37:09 -0700
> From: jbarnett@gremlin.nrtc.northrop.com
>
> if you wanted to COMPILER-LET several
> variables that were consumed by the same macro, the combinatorics of your
> solution would be bad news.
I don't think so. The problem comes in when you have several variables
that are used by several macros.
> Further, in your solution, the scope is wrong.
Could you please explain why you think the scoping is "wrong"?
> In any event, I hope that COMPILER-LET remains in the language. I have found it
> an easy and natural construct to use for implementing various language
> extentions.
I would like to see some actual examples of how you've been using it in
real code. All the ones we've dealt with so far have been artificially
contrived.
> In addition, it seems that it should be trivial to make EVALed
> forms enjoy the same semantics that the compiler proffers.
Actually not. As we've already discussed on the cl-compiler mailing
list, it would require all implementations to have their interpreters
do a code-walking prepass to perform macroexpansion, instead of
allowing macroexpansion to be performed in parallel with evaluation.
Some implementations do work that way already, but the change for the
rest would hardly be "trivial".
-Sandra
-------
∂27-Sep-88 1307 CL-Compiler-mailer Re: COMPILER-LET
Received: from gremlin.nrtc.northrop.com by SAIL.Stanford.EDU with TCP; 27 Sep 88 13:07:46 PDT
Received: from tribble by gremlin.nrtc.northrop.com id aa04128;
27 Sep 88 13:05 PDT
To: Sandra J Loosemore <sandra%defun@cs.utah.edu>
cc: jbarnett@gremlin.nrtc.northrop.com, common-lisp@sail.stanford.edu,
cl-compiler@sail.stanford.edu
Subject: Re: COMPILER-LET
In-reply-to: Your message of Tue, 27 Sep 88 13:19:20 -0600.
<8809271919.AA06137@defun.utah.edu>
Date: Tue, 27 Sep 88 13:05:46 -0700
From: jbarnett@gremlin.nrtc.northrop.com
Here's an example were COMPILER-LET helps and replacing it with a
MACRO-LET seems rather unnatural. It is simplified from the
implementation of CLOCKS, a shell that supports multiple distributd
agents, each with its own blackboard. There is a general language form,
that for the current discussion, we will say looks like
(VAL THING PNAME)
where THING is either a hypothesis on an agent's blackboard or a
representation of an agent -- some specialized knowledge sources can be
scoped into multiple agents. The VAL form can be either an odd or even
numbered arg to SETF and either refers to the PNAME property of a
hypothesis or that property on the header of THING's blackboard. The
access in each case is quite different. The VAL macro has an
implementation that resembles
(DEFMACRO VAL (THING PNAME)
(IF (MEMBER THING *SCOPED-AGENTS*)
(EXPAND-FOR-AGENT THING PNAME)
(EXPAND-FOR-HYPOTHESIS THING PNAME)))
Further, there is a language form that enables specialized knowledge
sources' accesses to multiple agents:
(DEFMACRO WITH-SCOPED-AGENT (AGENT &BODY BODY)
`(COMPILER-LET((*SCOPED-AGENTS* (CONS ',AGENT *SCOPED-AGENTS*)))
,@BODY))
Of course there is a top-level definition like
(DEFVAR *SCOPED-AGENTS* NIL)
There doesn't seem to be anything unclear or arcane about the above.
Further, if the expansion of VAL depends upon other things that are
context dependent (it does), it is hard to think of a cleaner
implementation tool that is independent of the implementation of the
underlying LISP compiler.
As to the question of making EVAL and the compiler compatible, I must
admit that I haven't written a CL system so I may be wrong in saying
that it is easy but two approaches immediately suggest themselves: The
first is that EVAL should just compile its argument, execute it and mark
it for the GC. This is what I always did in the LISPs that I
implemeneted and the gain in compatibility was a joy. The second
approach is for those who find the first suggestion fatuous.
In point of fact, an EVAL function for CL must keep around an
environment object -- else how can it know which variables are lexical
and know which operators are really lexical macros? Why not just put
the COMPILER-LETed special variables in the environemnt object--marked
as such--then PROGV or PROGW them exactly around EVAL's macro expansion
activity. How could this possibly be a large change to current
implementations?
∂30-Sep-88 0933 Common-Lisp-mailer Results on Lisp Profilers
Received: from PROOF.ERGO.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 30 Sep 88 09:33:30 PDT
Received: from PROOF.ERGO.CS.CMU.EDU by PROOF.ERGO.CS.CMU.EDU; 30 Sep 88 12:31:38 EDT
To: common-lisp@sail.stanford.edu
cc: lew@lucid.com
Subject: Results on Lisp Profilers
Date: Fri, 30 Sep 88 12:31:30 EDT
Message-ID: <9991.591640290@PROOF.ERGO.CS.CMU.EDU>
From: Conal.Elliott@PROOF.ERGO.CS.CMU.EDU
A couple of weeks ago, I posted an inquiry to this mailing list about the
existence of profiling tools for Common Lisp. Here's a summary of my
responses:
CMU's Common Lisp has a timing package. Apparently, it is "public domain, and
public domain, and people can get our library from ISI or some such
organization in California." It didn't appear very useful for my purposes
because "if functions A and B are profiled, and A calls B, then the accumulated
time for A will include time spent in B." Since a lot of my code is recursive
(directly and indirectly), this policy would be unusable.
Stuart Shapiro at Buffalo (shapiro@cs.buffalo.edu) sent me his profiler. In
this tool, "statistics kept are number of times called and amount of run-time
spent in the function (minus time spent in dynamically embedded profiled
functions)."
Finally, Lois Lew from Lucid (sun-support@lucid.com on ARPA or
...!sun!edsel!sun-support on UUCP) sent me their profiler. It also accounts
for dynamically embedded profiled functions. In addition to timing, it also
shows how much heap space was allocated during the function's execution. This
seems a very useful feature, given the "buy now -- pay later" aspect of most
garbage collectors. I don't have enough experience with it yet, but so far I
like it. Here is an example of its output:
-> (print-all-monitors)
Monitor information for SIMPL
Number of calls : 10
Time (secs) : 0.291
Avg. time / call : 0.029
Words of consing : 2770
Avg. words / call : 277.000
Monitor information for GC
Number of calls : 1
Time (secs) : 0.116
Avg. time / call : 0.116
Words of consing : 0
Avg. words / call : 0.000
Monitor information for COPY-LTERM
Number of calls : 2
Time (secs) : 0.039
Avg. time / call : 0.019
Words of consing : 32
Avg. words / call : 16.000
Monitor information for SOLVE
Number of calls : 2
Time (secs) : 0.796
Avg. time / call : 0.398
Words of consing : 6766
Avg. words / call : 3383.000
NIL
->
- Conal
∂01-Oct-88 1449 Common-Lisp-mailer Issue: DOTTED-MACRO-FORMS (Version 2)
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 1 Oct 88 14:49:47 PDT
Received: from Salvador.ms by ArpaGateway.ms ; 01 OCT 88 14:47:21 PDT
Date: 1 Oct 88 14:47 PDT
From: masinter.pa@Xerox.COM
to: Common-Lisp@sail.stanford.edu
cc: goldman@vaxa.isi.edu
Subject: Issue: DOTTED-MACRO-FORMS (Version 2)
Message-ID: <881001-144721-2149@Xerox>
Well, there is a large cost associated with adding another declaration that
has semantic import.
Didn't we have some issue about whether
(EQ L (APPLY #'(LAMBDA (&REST X) X) L))
and was
(APPLY #'(LAMBDA (&REST X) X) '(A B . C))
an error?
although I forget its name offhand. Isn't this related? I.e., can't we
assume that argument lists don't end in dotted pairs?
I'd hope that they'd be resolved consistantly. My implementor's hat would
like to see APPLY have the ability to spread its arguments and make &REST
cons if it had to. Somewhat inconsistent with my original opinion on dotted
macros.
I guess I wasn't convinced by Neil's example, so I think I'm going to
support :DISALLOW.
!
Issue: DOTTED-MACRO-FORMS
References: forms (p54), lists and dotted lists (pp26-27),
DEFMACRO (p145), destructuring macro arguments (p146)
Category: CLARIFICATION
Edit history: 28-Jun-88, Version 1 by Pitman
1-Oct-88, Version 2 by Masinter
Problem Description:
CLtL is not explicit about whether macro forms may be dotted lists.
p54 says that only certain forms are "meaningful": self-evaluating
forms, symbols, and "lists".
pp26-27 defines "list" and "dotted list". It goes on to say
``Throughout this manual, unless otherwise specified, it is an
error to pass a dotted list to a function that is specified
to require a list as an argument.''
p146 states that in DEFMACRO destructuring, ``the argument
form that would match the parameter is treated as a
(possibly dotted) list, to be used as an argument forms list
for satisfying the parameters in the embedded lambda list.''
It goes on to say that ". var" is treated like "&rest var"
at any level of the defmacro lambda-list.
Proposal (DOTTED-MACRO-FORMS:DISALLOW):
Specify that it is an error for a macro form to be a dotted list.
Rationale:
Dotted lists are a possible symptom of program syntax error.
Allowing implementations to check for this error may catch enough
errors to justify the loss of program flexibility.
Test Case:
#1: (DEFMACRO MACW (&WHOLE W &REST R) `(- ,(CDR W)))
(MACW . 1) => ??
#2: (DEFMACRO MACR (&REST R) `(- ,R))
(MACR . 1) => ??
#3: (DEFMACRO MACX (&WHOLE W) `(- ,(CDR W)))
(MACX . 1)
(MACW . 1) would be an error under this proposal.
(MACR . 1) would be an error under this proposal.
Current Practice:
A. Some implementations bind W to (MACW . 1) in #1 and #3
and bind R to 1 in #1 and #2.
B. Some implementations bind W to (MACW . 1) in #3
and signal a syntax error in #1 and #2.
C. Some implementations signal a syntax error in #1, #2, and #3.
Symbolics Genera is such an implementation.
Cost to Implementors:
As written, this proposal doesn't require implementations to check for
the error condition.
Cost to Users:
Some users depend on this behavior in current implementations, although
such use is not widespread.
Benefits:
People would know what to expect.
Aesthetics:
Mixed opinion; certainly it is better to specify whether they are allowed
or an error than to be vague. Some feel that disallowing dotted macro
forms makes the language cleaner.
Discussion:
Goldman@VAXA.ISI.EDU raised this issue on Common-Lisp.
This issue came up primarily in the context of program-written programs;
a macro used in the program generated code might occasionally use
a dotted tail to a list to explicitly represent special conditions.
Allowing dotted macro forms may blur the data/code distinction too much,
particularly for people who are new to Lisp.
Some people believe that there's no reason to unnecessarily restrict
&WHOLE and/or &REST since there is no computational overhead and since
the interpretation, if there is one at all, is pretty well agreed upon.
∂02-Oct-88 1909 Common-Lisp-mailer Issue: DOTTED-MACRO-FORMS (Version 2)
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 2 Oct 88 19:08:53 PDT
Received: from GRYPHON.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 469179; Sun 2-Oct-88 22:07:31 EDT
Date: Sun, 2 Oct 88 22:06 EDT
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Issue: DOTTED-MACRO-FORMS (Version 2)
To: masinter.pa@Xerox.COM
cc: Common-Lisp@sail.stanford.edu, goldman@vaxa.isi.edu
In-Reply-To: <881001-144721-2149@Xerox>
Message-ID: <881002220656.7.KMP@GRYPHON.SCRC.Symbolics.COM>
I'm pretty neutral on this issue.
I agree Goldman's example is not very compelling. I don't see
any reason not to have done (?? WFF) rather than (?? . WFF).
On the other hand, I think macro forms are "expressions outside
the language" which the macro facility is responsible for
translating to "forms", so I could buy a little flexibility here.
But in the end there's little call for this and I think the
error checking arguments win out.
Then again, disallowing dotted lists will make &REST etc. seem
more like they are in functions. There was a deliberate attempt
to make these very syntactically similar in other ways, and I
think it's worth carrying through on it.
Since I could go for it either way, but I'm quite content with
your decision to present only the DISALLOW option (which I guess
is effectively the same as what I called EXPLICITLY-VAGUE in the
previous writeup ... I guess you've been taking lessons from the
political campaigns on "spin control" ...).
∂03-Oct-88 1250 Common-Lisp-mailer [Re: Issue: DOTTED-MACRO-FORMS (Version 2)]
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 3 Oct 88 12:50:08 PDT
Posted-Date: Mon, 03 Oct 88 11:48:31 PST
Message-Id: <8810031948.AA20503@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51)
id AA20503; Mon, 3 Oct 88 12:48:38 PDT
To: Common-Lisp@sail.stanford.edu
From: goldman@vaxa.isi.edu
Subject: [Re: Issue: DOTTED-MACRO-FORMS (Version 2)]
Cc: masinter.pa@xerox.com
Date: Mon, 03 Oct 88 11:48:31 PST
Sender: goldman@vaxa.isi.edu
Well, there is a large cost associated with adding another declaration
that has semantic import.
I understand why adding declarations WITHOUT semantic import is always
easy on implementors. But I don't understand how adding declarations
WITH semantic import is necessarily costly for them. In particular, since
people whom I assume to be knowledgeable stated that it would be trivial
form implementations to either accept or reject dotted macro forms, I don't
see why a user declaration to control this on a per macro basis would
be very costly for them. In particular, why would it be any more costly
than any other clarification of the dotted macro issue? (Except for specifying
that "it is an error" rather than "an error is signalled", which
would let all the implementors continue to be inconsistent, but has no
other redeeming characteristics in this situation.)
Didn't we have some issue about whether
(APPLY #'(LAMBDA (&REST X) X) '(A B . C))
an error? although I forget its name offhand. Isn't this related? I.e.,
can't we assume that argument lists don't end in dotted pairs?
Since it is not legal to APPLY macros, and since macro lambda lists already
have a syntax that allows things NOT allowed in lambda lists of
APPLYable lambda, the resolution of one issue doesn't NECESSARILY tell
us how to resolve the other.
However, I would very definitely see a virtue in having the language
defined so that it was guaranteed that whenever I saw an &REST variable
it was guaranteed to be bound to a non-dotted list (or NIL).
I wouldn't be terribly bothered by totally outlawing dotted argument lists,
if it were done uniformly (although I would prefer that they be allowed
in cases where the programmer explicitly indicated a willingness to
accept them.) But, unless I misunderstood the :DISALLOW proposal,
only top-level dotted lists are disallowed. One could still write
(MY-MACRO (x . :all) (foo x) (fum x))
where the dotted argument is not at the top level, and
receive the parameters with either
(var-and-control &body forms)
or with
((var . control) &body forms)
or even
((var &rest control) &body forms)
which binds the &rest to (x . :all).
Why are top-level dotted argument lists so much more objectionable than
embedded ones, so that it makes you want to have a different semantics for
the embedded lambda lists in the macro syntax?
Neil
∂05-Oct-88 1107 Common-Lisp-mailer Hash Tables vs. Alists
Received: from tut.cis.ohio-state.edu by SAIL.Stanford.EDU with TCP; 5 Oct 88 11:07:08 PDT
Received: by tut.cis.ohio-state.edu (5.54/2.880920)
id AA21371; Wed, 5 Oct 88 14:05:04 EDT
Date: Wed, 5 Oct 88 14:05:04 EDT
From: welch@tut.cis.ohio-state.edu (Arun Welch)
Message-Id: <8810051805.AA21371@tut.cis.ohio-state.edu>
To: common-lisp@sail.stanford.edu
Subject: Hash Tables vs. Alists
Someone over here asked me today "At what point do hash tables get
more efficient than alists?". It seems to me that there are a number
of issues in this question, namely:
1) How well the implementation computes hash keys.
2) How well the implementation rehashes the table.
3) Whether all the memory elements in the hash table are allocated all
at once.
4) How the implementation walked the alist. I seem to remember seeing
somewhere that Zetalisp machines were efficient for fairly large
alists due to harware support for walking the list, but I can't
remember where, of if I'm just remembering wrong.
Has anyone actually done a study of this, or even have some pretty
good rules-of-thumb other than "if it's big, use a hash table"?
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
∂05-Oct-88 1156 Common-Lisp-mailer Hash Tables vs. Alists
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 5 Oct 88 11:56:14 PDT
Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 471060; Wed 5-Oct-88 14:53:52 EDT
Date: Wed, 5 Oct 88 14:53 EDT
From: David A. Moon <Moon@STONY-BROOK.SCRC.Symbolics.COM>
Subject: Hash Tables vs. Alists
To: Arun Welch <welch@tut.cis.ohio-state.edu>
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8810051805.AA21371@tut.cis.ohio-state.edu>
Message-ID: <19881005185309.0.MOON@EUPHRATES.SCRC.Symbolics.COM>
In Symbolics Genera 7.0 and later, the make-hash-table/gethash family
of functions choose an appropriate internal representation (hash table,
alist, linearly searched array) based on the test function and the size
of the table, and automatically switch representations when the table
grows or shrinks. Thus the application programmer doesn't have to
think about it. The tradeoff point between linear search and hash table
is based on measurements and is surprisingly high when the test function
is EQ or EQL, since a linear search with those test functions can be
very fast.
I don't know if any other Common Lisp implementations do this, although
I don't see any reason why they couldn't. Just because the function
is named make-hash-table doesn't mean it actually has to be implemented
with a hash-table.
∂05-Oct-88 1203 Common-Lisp-mailer Hash Tables vs. Alists
Received: from SAPSUCKER.SCRC.Symbolics.COM ([128.81.41.223]) by SAIL.Stanford.EDU with TCP; 5 Oct 88 12:03:37 PDT
Received: from EVENING-GROSBEAK.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 254559; Wed 5-Oct-88 14:36:16 EDT
Date: Wed, 5 Oct 88 14:34 EDT
From: Scott McKay <SWM@SAPSUCKER.SCRC.Symbolics.COM>
Subject: Hash Tables vs. Alists
To: welch@tut.cis.ohio-state.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8810051805.AA21371@tut.cis.ohio-state.edu>
Message-ID: <19881005183430.3.SWM@EVENING-GROSBEAK.SCRC.Symbolics.COM>
Date: Wed, 5 Oct 88 14:05:04 EDT
From: welch@tut.cis.ohio-state.edu (Arun Welch)
Someone over here asked me today "At what point do hash tables get
more efficient than alists?". It seems to me that there are a number
of issues in this question, namely:
1) How well the implementation computes hash keys.
2) How well the implementation rehashes the table.
3) Whether all the memory elements in the hash table are allocated all
at once.
4) How the implementation walked the alist. I seem to remember seeing
somewhere that Zetalisp machines were efficient for fairly large
alists due to harware support for walking the list, but I can't
remember where, of if I'm just remembering wrong.
Has anyone actually done a study of this, or even have some pretty
good rules-of-thumb other than "if it's big, use a hash table"?
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
If you are using Genera, you can just use "tables", which dynamically
change from alists to real hash-table based on various parameters which
you can specify. The point is that the Genera table system chooses the
representation which gives the best performance and uses that, and you
yourself don't have to worry about it. Unless you want to, of course.
∂05-Oct-88 1409 Common-Lisp-mailer Re: Hash Tables vs. Alists
Received: from gremlin.nrtc.northrop.com by SAIL.Stanford.EDU with TCP; 5 Oct 88 14:09:33 PDT
Received: from tribble by gremlin.nrtc.northrop.com id aa22827;
5 Oct 88 14:07 PDT
To: Arun Welch <welch@tut.cis.ohio-state.edu>
cc: common-lisp@sail.stanford.edu, jbarnett@gremlin.nrtc.northrop.com
Subject: Re: Hash Tables vs. Alists
In-reply-to: Your message of Wed, 05 Oct 88 14:05:04 -0400.
<8810051805.AA21371@tut.cis.ohio-state.edu>
Date: Wed, 05 Oct 88 14:07:34 -0700
From: jbarnett@gremlin.nrtc.northrop.com
I ran some timing tests in Symbolics 6.1 (pre Genera) and found that alist
searching was better than hash tables when the number of keys was less than
75 or so. This test used EQ and did not include the little extras like GC
overhead and the gork that transpired when worlds were saved and restored.
My guess is that the break even point would be much higher if all things
were considered.
As to the fact that Genera skillfully switches representation: don't
forget that there is a significant overhead for going into and out of generic
functions, flavor methods, flavor functions, etc., to finally let the machine
coded alist search hum away. I too would like to know where the current
trade off is since I quite using hash tables except for monsters.
∂08-Oct-88 0740 Common-Lisp-mailer 1989 conference on Lisp and History of Lisp -- advance notice
Received: from murren.ai.mit.edu ([18.43.0.179]) by SAIL.Stanford.EDU with TCP; 8 Oct 88 07:40:16 PDT
Received: by murren.ai.mit.edu (5.59/1.5)
id AA15795; Sat, 8 Oct 88 10:36:50 EDT
Date: Sat, 8 Oct 88 10:36:50 EDT
From: hal@murren.ai.mit.edu (Hal Abelson)
Message-Id: <8810081436.AA15795@murren.ai.mit.edu>
To: common-lisp@sail.stanford.edu
Subject: 1989 conference on Lisp and History of Lisp -- advance notice
Reply-To: hal@zurich.ai.mit.edu
HAPPY 30TH BIRTHDAY FOR LISP CONFERENCE
In recognition of the 30th birthday of the Lisp programming language,
the ACM is sponsoring a special conference on Lisp and the history of
Lisp, to be held at MIT, November 28 through December 1 1989.
Part of the conference will deal with technical issues of current
interest to the Lisp community (similar to Lisp presentations at the
Lisp and Functional Programming conferences). There also be sessions
devoted to historical papers, evolution of Lisp implementation
technology, perspectives on the past and future of Lisp, and so on.
A formal call for abstracts (which will be due next May) will appear
in a few months.
In the meantime we wanted to solicit your advice about appropriate
special events for this conference. For example, people have
suggested presenting awards for distinguished contributions to Lisp.
Are there particular panel discussions you would like to see? Or
other events you think would be appropriate for a birthday
celebration?
Please mail us your suggestions.
For the program committee:
Dick Gabriel
Guy Steele
Jan Zubkoff
Hal Abelson
send suggestions to
Hal Abelson
MIT
545 Technology Square
Cambridge, MA 02129
hal@zurich.ai.mit.edu
∂10-Oct-88 0944 Common-Lisp-mailer Re: Common Lisp: The Reference
Received: from tut.cis.ohio-state.edu by SAIL.Stanford.EDU with TCP; 10 Oct 88 09:44:01 PDT
Received: by tut.cis.ohio-state.edu (5.54/2.880920)
id AA21378; Mon, 10 Oct 88 12:42:37 EDT
Date: Mon, 10 Oct 88 12:42:37 EDT
From: welch@tut.cis.ohio-state.edu (Arun Welch)
Message-Id: <8810101642.AA21378@tut.cis.ohio-state.edu>
To: common-lisp@sail.stanford.edu
Subject: Re: Common Lisp: The Reference
All the replies to my original question about this book were of the
sort "If you hear anything, I'd be interested too", so it was pretty
nice that Franz sent us a review copy of CLtR along with the review
copy of Allegro that we ordered. CLtR is exactly that, a reference to
CL. No new insights to the language, no programmers tips or style
issues, just an alphabetic listing of every function in the language, it's
arguments and usage, and some examples of it. I'm not putting it down
by this, it does a very good job of being a reference to the language,
and I think I'm gonna get a copy to put on my shelf. It's kinda like
the Glossary section of Cherniak et al's _AI Programming_, except
every single function/whatever is documented, even all the various
read macros. Nutshell review: If you know CL inside and out, then
you probably don't need this. However, if you would like a real
language reference, then it's a nice beast to have, and makes a good
companion to Steele.
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
∂13-Oct-88 1530 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 13 Oct 88 15:29:21 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Thu, 13 Oct 88 14:13:09 PDT
Date: Thu, 13 Oct 88 14:13:09 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <881013141309.20600216@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: Code walker wanted.
Date: Thu, 13-OCT-1988 14:09 MST
X-VMS-Mail-To: @CL,POTHIERS
Anyone know where I can get Common LISP source to walk lisp code?
Thanks in advance! Steve Pothier, SAIC, Tucson
∂13-Oct-88 1806 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 13 Oct 88 15:29:21 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Thu, 13 Oct 88 14:13:09 PDT
Date: Thu, 13 Oct 88 14:13:09 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <881013141309.20600216@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: Code walker wanted.
Date: Thu, 13-OCT-1988 14:09 MST
X-VMS-Mail-To: @CL,POTHIERS
Anyone know where I can get Common LISP source to walk lisp code?
Thanks in advance! Steve Pothier, SAIC, Tucson
∂13-Oct-88 1909 Common-Lisp-mailer
Received: from NMFECC.ARPA by SAIL.Stanford.EDU with TCP; 13 Oct 88 15:29:21 PDT
Received: from tuva.sainet.mfenet by ccc.mfenet with Tell via MfeNet ;
Thu, 13 Oct 88 14:13:09 PDT
Date: Thu, 13 Oct 88 14:13:09 PDT
From: POTHIERS%TUVA.SAINET.MFENET@NMFECC.ARPA
Message-Id: <881013141309.20600216@NMFECC.ARPA>
To: COMMON-LISP@SAIL.STANFORD.EDU
Subject: Code walker wanted.
Date: Thu, 13-OCT-1988 14:09 MST
X-VMS-Mail-To: @CL,POTHIERS
Anyone know where I can get Common LISP source to walk lisp code?
Thanks in advance! Steve Pothier, SAIC, Tucson
∂19-Oct-88 0754 Common-Lisp-mailer Program Call Structure
Received: from crash.cs.umass.edu ([128.119.40.235]) by SAIL.Stanford.EDU with TCP; 19 Oct 88 07:54:14 PDT
Received: from vax9.cs.umass.edu by crash.cs.umass.edu (5.59/Ultrix2.0-B)
id AA02163; Wed, 19 Oct 88 10:56:19 edt
Message-Id: <8810191456.AA02163@crash.cs.umass.edu>
Date: Wed, 19 Oct 88 10:53 EDT
From: ELIOT@cs.umass.EDU
Subject: Program Call Structure
To: common-lisp@sail.stanford.EDU
X-Vms-To: IN%"common-lisp@sail.stanford.EDU"
I have considered building a browser to inspect the call structure
of a Lisp program, but Common Lisp does not seem to provide the
primitives needed for this. Theoretically one can use a code walker to
determine the call structure, but this does not really work because too
many implementations include macros that expand into implementation
specific special forms. Furthermore, to make it work smoothly there
needs to be some way to determine the source file of a function,
and this functionality is missing from Common Lisp. The Lispm
function who-calls provides the required information, but it is
not implemented efficiently, and it is not standard.
This table describes four functions which would provide the required
primitive functionality to implement a browser capable of showing
the call structure of a Lisp program (similar perhaps to InterLisp's
MasterScope).
Function To Functions Function To Variables
---------------------------------------------
Upward | Who-Calls | Who-References |
|-----------------------|-------------------|
Downward | What-Calls | What-References |
---------------------------------------------
Who-Calls: Maps from a function spec to a list of functions that call it.
What-Calls: Maps from a function spec to a list of functions called by it.
Who-References: Maps from a variable to a list of functions that reference it.
What-References: Maps from a function spec to a list of variables
referenced by it.
None of these functions produce any printed output. That functionality can
be implemented using these primitives if desired.
I have not tried to specify exactly what a function-spec means. At least
it should include a symbol that names a Defuned function. Compiled
function objects, generic functions and methods should also be acceptable.
∂19-Oct-88 1427 Common-Lisp-mailer Re: Program Call Structure
Received: from Sun.COM by SAIL.Stanford.EDU with TCP; 19 Oct 88 14:27:23 PDT
Received: from snail.Sun.COM by Sun.COM (4.0/SMI-4.0)
id AA10690; Wed, 19 Oct 88 14:24:02 PDT
Received: from clam.sun.com by snail.Sun.COM (4.0/SMI-4.0)
id AA23252; Wed, 19 Oct 88 14:26:55 PDT
Received: by clam.sun.com (3.2/SMI-3.2)
id AA03555; Wed, 19 Oct 88 14:27:36 PDT
Date: Wed, 19 Oct 88 14:27:36 PDT
From: cperdue@Sun.COM (Cris Perdue)
Message-Id: <8810192127.AA03555@clam.sun.com>
To: ELIOT@cs.umass.EDU, common-lisp@sail.stanford.EDU
Subject: Re: Program Call Structure
> This table describes four functions which would provide the required
> primitive functionality to implement a browser capable of showing
> the call structure of a Lisp program (similar perhaps to InterLisp's
> MasterScope).
>
> Function To Functions Function To Variables
> ---------------------------------------------
> Upward | Who-Calls | Who-References |
> |-----------------------|-------------------|
> Downward | What-Calls | What-References |
> ---------------------------------------------
In my experience, e.g. developing Sun's Program Analyzer for
Common Lisp, things are more complicated. One issue is inlining
of function calls. Some source-level calls "disappear" during
compilation and calls to internal routines can "appear". Another
issue is calls that occur due to macro expansion, without being
written into the source code.
One thing you may want to do with call structure information is to edit
the calls on a function. For this purpose you want to edit the
definitions of macros that expand into calls on the function, and not
edit every invocation of the macros.
-Cris
∂21-Oct-88 1343 Common-Lisp-mailer CL for Connection Machine?
Received: from tut.cis.ohio-state.edu by SAIL.Stanford.EDU with TCP; 21 Oct 88 13:42:59 PDT
Received: by tut.cis.ohio-state.edu (5.54/2.880920)
id AA25614; Fri, 21 Oct 88 16:42:13 EDT
Date: Fri, 21 Oct 88 16:42:13 EDT
From: welch@tut.cis.ohio-state.edu (Arun Welch)
Message-Id: <8810212042.AA25614@tut.cis.ohio-state.edu>
To: common-lisp@sail.stanford.edu
Subject: CL for Connection Machine?
Does such a thing exist? Does it have PCL? What sort of parallelism
extensions does it have? Enquiring minds want to know....
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
∂21-Oct-88 2123 Common-Lisp-mailer Re: Program Call Structure
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by SAIL.Stanford.EDU with TCP; 21 Oct 88 21:23:26 PDT
Received: from F.ILA.Dialnet.Symbolics.COM (FUJI.ILA.Dialnet.Symbolics.COM) by Riverside.SCRC.Symbolics.COM via DIAL with SMTP id 289523; 22 Oct 88 00:22:38 EDT
Date: Fri, 21 Oct 88 23:27 EDT
From: Robert W. Kerns <RWK@F.ILA.Dialnet.Symbolics.COM>
Subject: Re: Program Call Structure
To: cperdue@Sun.COM, ELIOT@cs.umass.EDU, common-lisp@sail.stanford.EDU
In-Reply-To: <8810192127.AA03555@clam.sun.com>
Message-ID: <19881022032726.6.RWK@F.ILA.Dialnet.Symbolics.COM>
Date: Wed, 19 Oct 88 14:27:36 PDT
From: cperdue@Sun.COM (Cris Perdue)
In my experience, e.g. developing Sun's Program Analyzer for
Common Lisp, things are more complicated. One issue is inlining
of function calls. Some source-level calls "disappear" during
compilation and calls to internal routines can "appear". Another
issue is calls that occur due to macro expansion, without being
written into the source code.
The Symbolics system records macroexpansions and in-linings (except for
certain extremely common ones) in the debugging-info for each function.
One thing you may want to do with call structure information is to edit
the calls on a function. For this purpose you want to edit the
definitions of macros that expand into calls on the function, and not
edit every invocation of the macros.
Actually, this isn't exactly true. In my experience, you want to edit
both. First, you want to edit the macro, to change the expansion. This
is easy if your tools can find references to a symbol in quoted list
structure. Then, however, you want to edit all the invocations of the
macro, to recompile the function, so you get the updated version of the
macro. (In fact, you'd like to have a function which automatically did
this).
∂24-Oct-88 1226 Common-Lisp-mailer common lisp ops5
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 24 Oct 88 12:25:45 PDT
Received: from cvaxa.sussex.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa05898; 24 Oct 88 18:58 BST
Received: from csuna by cvaxa.sussex.ac.uk; Mon, 24 Oct 88 17:35:38 BST
From: John Williams <johnw%cvaxa.sussex.ac.uk@NSS.Cs.Ucl.AC.UK>
Date: Mon, 24 Oct 88 17:39:04 BST
Message-Id: <26740.8810241639@csuna.cvaxa.sussex.ac.uk>
To: common-lisp@sail.stanford.edu, tomk@cvaxa.sussex.ac.uk
Subject: common lisp ops5
I understand that there is public domain Common Lisp
version of Forgy's OPS-5. Can anyone suggest where
I might get hold of a copy, preferably from within
the UK.
Thanks,
John Williams
School of Cognitive Science, University of Sussex
johnw@cvaxa.sussex.ac.uk
∂24-Oct-88 1439 Common-Lisp-mailer Public Domain OPS5 available.
Received: from CENTRO.SOAR.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 24 Oct 88 14:39:07 PDT
Received: from CENTRO.SOAR.CS.CMU.EDU by CENTRO.SOAR.CS.CMU.EDU; 24 Oct 88 17:34:49 EDT
To: common-lisp@sail.stanford.edu
cc: johnw%cvaxa.sussex.ac.uk@nss.cs.ucl.ac.uk
Subject: Public Domain OPS5 available.
Date: Mon, 24 Oct 88 17:34:46 EDT
Message-ID: <25473.593732086@CENTRO.SOAR.CS.CMU.EDU>
From: Brian.Milnes@CENTRO.SOAR.CS.CMU.EDU
The Soar Project's Production System Machine subgroup, distributes
free of cost by electronic mail and magnetic tape, C. Lany Forgy's
fully pulic domain original Franz Lisp OPS5 and a coarse port to
Common Lisp.
The Soar/PSM group is directed by Allen Newell and C. Lany Forgy and
is dedicated to efficiently implementing recognize/act technologies.
We also distribute OPS5 manuals and a collection of our research
papers.
For more information, please mail to psm-requests@centro.soar.cs.cmu.edu, or
The Soar Group
C/O Kathryn Swedlow
Department of Computer Science
Carnegie Mellon University
Pittsburgh, PA 15213-3890
∂25-Oct-88 0652 Common-Lisp-mailer common lisp ops5
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 25 Oct 88 06:50:02 PDT
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa04193; 25 Oct 88 14:11 BST
Received: from xenakis by mordell.maths.bath.AC.UK id aa24447;
25 Oct 88 13:24 BST
To: johnw <@NSS.Cs.Ucl.AC.UK:johnw@cvaxa.sussex.ac.uk>
CC: common-lisp@sail.stanford.edu, tomk%cvaxa.sussex.ac.uk@NSS.Cs.Ucl.AC.UK
In-reply-to: John Williams's message of Mon, 24 Oct 88 17:39:04 BST <26740.8810241639@csuna.cvaxa.sussex.ac.uk>
Subject: common lisp ops5
Date: Tue, 25 Oct 88 13:24:15 BST
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
I have one such. There is another one from SOAR. If you want mine
let me know, I run it on Poplog/CL amongst others.
==John
∂25-Oct-88 1840 Common-Lisp-mailer Re: Program Call Structure
Received: from uunet.UU.NET by SAIL.Stanford.EDU with TCP; 25 Oct 88 18:40:35 PDT
Received: from mcvax.UUCP by uunet.UU.NET (5.59/1.14) with UUCP
id AA16924; Tue, 25 Oct 88 21:39:54 EDT
Received: by mcvax.cwi.nl via EUnet; Tue, 25 Oct 88 20:42:19 +0100 (MET)
Received: from ski.cs.vu.nl by botter.cs.vu.nl id aa27511; 25 Oct 88 10:30 MET
Date: Tue, 25 Oct 88 10:30:36 MET
From: "J. A. 'Biep' Durieux" <mcvax!cs.vu.nl!biep@uunet.UU.NET>
To: ELIOT@cs.umass.edu
Cc: common-lisp@sail.stanford.edu
Subject: Re: Program Call Structure
Message-Id: <8810251030.aa07483@ski.cs.vu.nl>
ELIOT@cs.umass.edu writes:
>This table describes four functions which would provide the required
>primitive functionality to implement a browser capable of showing
>the call structure of a Lisp program (similar perhaps to InterLisp's
>MasterScope).
>
> Function To Functions Function To Variables
> ---------------------------------------------
>Upward | Who-Calls | Who-References |
> |-----------------------|-------------------|
>Downward | What-Calls | What-References |
> ---------------------------------------------
>
>Who-Calls: Maps from a function spec to a list of functions that call it.
>What-Calls: Maps from a function spec to a list of functions called by it.
>Who-References: Maps from a variable to a list of functions that reference it.
>What-References: Maps from a function spec to a list of variables
>referenced by it.
(1) I think the names are unclear: "what calls foo" is ambiguous, and then the
change from personified (who) to unpersonified (what) is unlogical.
I would propose "who-calls" versus "whom-calls". No ambiguity, and no
change.
(2) I would like to see a "(who-changes <variable>)" and a "(whom-changes
<function>)" added, for dealing with side-effects. This could also be
done by "(who-calls '(setf <var> ...)), perhaps. A set of functions-
to-be-examined has to be provided anyway.
Otherwise I like the proposal.
Biep.
∂03-Nov-88 1751 Common-Lisp-mailer LALR parser generator
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 3 Nov 88 17:50:52 PST
Received: from Semillon.ms by ArpaGateway.ms ; 03 NOV 88 17:39:16 PST
Date: 3 Nov 88 17:35 PST
From: Wescoat.pa@Xerox.COM
Subject: LALR parser generator
To: common-lisp@Sail.Stanford.EDU
Reply-to: Wescoat.pa@Xerox.COM
Message-ID: <881103-173916-4284@Xerox>
Does anyone know of the existence of an LALR parser
generator in Common Lisp?
Any leads appreciated.
Michael Wescoat
∂04-Nov-88 0143 Common-Lisp-mailer LALR parser generator
Received: from forsythe.stanford.edu by SAIL.Stanford.EDU with TCP; 4 Nov 88 01:43:17 PST
Received: by Forsythe.Stanford.EDU; Fri, 4 Nov 88 01:43:19 PST
Received: by tub.UUCP; Fri, 4 Nov 88 10:40:46 +0200; AA12886
Received: by tub-tfs.uucp (4.0/SMI-3.0DEV3)
id AA02097; Fri, 4 Nov 88 10:42:59 +0100
Date: Fri, 4 Nov 88 10:42:59 +0100
From: alti%tub-tfs.uucp%tub.BITNET@Forsythe.Stanford.EDU (Thorsten Altenkirch)
Message-Id: <8811040942.AA02097@tub-tfs.uucp>
To: Wescoat.pa%Xerox.COM@tub.UUCP
Cc: common-lisp@Sail.Stanford.EDU
In-Reply-To: Wescoat.pa%Xerox.COM@tub.UUCP's message of 3 Nov 88 17:35 PST
<881103-173916-4284@Xerox>
Subject: LALR parser generator
I wrote one at my last job. They used it for parsing of a
knowledge representation language. If you like, I would give it to you
as a base for own developments. It was written on a SYMBOLICS, but
doesn't use any special features. The point is that I wouldn't like it
if my company get the information that I am mailing their 'trade
secrets' around... But I think it is'nt such a big problem, because
West Berlin is far away from Stanford.
Thorsten
∂10-Nov-88 1311 Common-Lisp-mailer backquote
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 10 Nov 88 13:11:29 PST
Posted-Date: Thu, 10 Nov 88 11:55:40 PST
Message-Id: <8811101955.AA11298@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA11298; Thu, 10 Nov 88 11:55:42 PST
To: common-lisp@sail.stanford.edu
Subject: backquote
Date: Thu, 10 Nov 88 11:55:40 PST
From: Don Cohen <donc@vaxa.isi.edu>
I don't understand the 3 line explanation of backquotes in backquotes
on p. 350 of CLtL. I'd appreciate some enlightenment. Also, I'd be
interested in whether backquote is capable of solving the problem below.
I surely don't see how to do it, but since I don't really understand
embedded backquotes I'm not sure it can't be done.
The problem:
Suppose we want to declare versions of existing functions that do type
checking, e.g., we want a protected version of (+ x y) which, if x and y
are both numbers returns their sum and otherwise returns nil. This could
be done by the following macro:
(defmacro protected-+ (x y)
`(let ((x ,x) (y ,y)) (and (numberp x) (numberp y) (+ x y))))
so that
(macroexpand '(protected-+ a b))
=>
(LET ((X A) (Y B))
(AND (NUMBERP X) (NUMBERP Y) (+ X Y)))
(The let assures that each argument is evaluated only once.)
Since there are many such functions to declare, we might want a macro
to define them, e.g.,
(define-protected + (numberp x) (numberp y))
would be a reasonable way to create the macro above.
If we try to define this macro in the straight forward way we start
out like so:
(defmacro define-protected (function &rest args)
`(defmacro ,(MAKE-PROTECTED-NAME function)
,(mapcar #'cadr args)
`(let ,(BUILD-LET-LIST args)
(and ,@args
,(BUILD-FUNCTION-CALL function args)))))
Unfortunately, it appears that BUILD-LET-LIST has to build an expression
with more commas than backquotes, which the backquote readmacro cannot do.
Another way to look at it is that I don't see how one backquote can
produce different backquoted expressions with varying numbers of commas.
∂10-Nov-88 1350 Common-Lisp-mailer backquote
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 10 Nov 88 13:49:40 PST
Return-Path: <@Think.COM:barmar@FAFNIR.THINK.COM>
Received: from sauron.think.com by Think.COM; Thu, 10 Nov 88 16:24:39 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Thu, 10 Nov 88 16:46:56 EST
Date: Thu, 10 Nov 88 16:47 EST
From: Barry Margolin <barmar@Think.COM>
Subject: backquote
To: Don Cohen <donc@vaxa.isi.edu>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811101955.AA11298@vaxa.isi.edu>
Message-Id: <19881110214739.8.BARMAR@OCCAM.THINK.COM>
Date: Thu, 10 Nov 88 11:55:40 PST
From: Don Cohen <donc@vaxa.isi.edu>
I don't understand the 3 line explanation of backquotes in backquotes
on p. 350 of CLtL. I'd appreciate some enlightenment. Also, I'd be
interested in whether backquote is capable of solving the problem below.
I surely don't see how to do it, but since I don't really understand
embedded backquotes I'm not sure it can't be done.
The problem:
Suppose we want to declare versions of existing functions that do type
checking, e.g., we want a protected version of (+ x y) which, if x and y
are both numbers returns their sum and otherwise returns nil. This could
be done by the following macro:
(defmacro protected-+ (x y)
`(let ((x ,x) (y ,y)) (and (numberp x) (numberp y) (+ x y))))
so that
(macroexpand '(protected-+ a b))
=>
(LET ((X A) (Y B))
(AND (NUMBERP X) (NUMBERP Y) (+ X Y)))
(The let assures that each argument is evaluated only once.)
Since there are many such functions to declare, we might want a macro
to define them, e.g.,
(define-protected + (numberp x) (numberp y))
would be a reasonable way to create the macro above.
If we try to define this macro in the straight forward way we start
out like so:
(defmacro define-protected (function &rest args)
`(defmacro ,(MAKE-PROTECTED-NAME function)
,(mapcar #'cadr args)
`(let ,(BUILD-LET-LIST args)
(and ,@args
,(BUILD-FUNCTION-CALL function args)))))
Unfortunately, it appears that BUILD-LET-LIST has to build an expression
with more commas than backquotes, which the backquote readmacro cannot do.
Another way to look at it is that I don't see how one backquote can
produce different backquoted expressions with varying numbers of commas.
The problem is that you are insisting on using the same argument names
in both places. I think it becomes possible if you drop that
requirement, and just use GENSYMs. However, I'm not going to try to
work it out, because I have a better idea:
It would be easier if protected-+ were defined to be a function, and I
don't see any reason why it shouldn't be (for efficiency,
DEFINE-PROTECTED could also include an INLINE proclamation).
(defmacro define-protected (function &rest arg-specs)
(let ((protected-name (make-protected-name function))
(args (mapcar #'cadr arg-specs)))
`(progn
(proclaim '(inline ,protected-name))
(defun ,protected-name ,args
(and ,@arg-specs
(,function .,args))))))
Here's another variant. This has the improvement (in my opinion) that
you don't build in assumptions about the format of the predicate call
(the MAPCAR #'CADR means that an argument can't be described as (and
(numberp x) (plusp x)).
(defmacro define-protected (function &rest arg-specs)
"(define-protected <function> &rest (<arg1> <type1>) ...)"
(let ((protected-name (make-protected-name function))
(args (mapcar #'car arg-specs)))
`(progn
(proclaim '(inline ,protected-name))
(defun ,protected-name ,args
,@(mapcar #'(lambda (arg-spec)
`(check-type ,.arg-spec))
arg-specs)
(,function .,args)))))
This allows you to use arbitrary type specifiers (which are completely
general because of the (SATISFIES predicate) type spec). In this case,
your example above becomes:
(define-protected + (x number) (y number))
barmar
∂10-Nov-88 1419 Common-Lisp-mailer backquote
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 10 Nov 88 14:19:34 PST
Posted-Date: Thu, 10 Nov 88 14:18:19 PST
Message-Id: <8811102218.AA14351@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA14351; Thu, 10 Nov 88 14:18:25 PST
To: Barry Margolin <barmar@think.com>
Cc: common-lisp@sail.stanford.edu
Subject: backquote
Date: Thu, 10 Nov 88 14:18:19 PST
From: Don Cohen <donc@vaxa.isi.edu>
I don't think the argument names are at all relevant - you're
welcome to use different names. Also, my specifications were
already completely general, since the car could have been a
lambda expression.
Your reply provides a solution to a different problem. I agree
that if I really only wanted to define protected functions, that
would be fine. However the question was really about whether
nested backquotes are really adequate for writing programs that
write programs that ...
Perhaps you believe that should never be necessary. I admit it
doesn't seem to arise every day, but I've seen it several times.
∂10-Nov-88 1455 Common-Lisp-mailer backquote
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 10 Nov 88 14:55:38 PST
Received: from BOBOLINK.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 490777; Thu 10-Nov-88 17:55:48 EST
Date: Thu, 10 Nov 88 17:55 EST
From: Kent M Pitman <KMP@STONY-BROOK.SCRC.Symbolics.COM>
Subject: backquote
To: donc@vaxa.isi.edu
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811101955.AA11298@vaxa.isi.edu>
Message-ID: <881110175533.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
I prefer the syntax (define-protected ((x fixnum) (y float)) (+ x y)).
In portable code, I would write:
(defmacro define-protected (op bvl &body forms)
(let ((vars (mapcar #'car bvl))
(types (mapcar #'cadr bvl)))
`(defmacro ,(intern (format nil "PROTECTED-~A" op)) ,vars
`(let ,(mapcar #'(lambda (var val type)
`(,var ,val))
',vars
(list ,@vars))
(when (and ,@',(mapcar #'(lambda (var type) `(typep ,var ',type))
vars types))
,@',forms)))))
However, in implementations (such as the Symbolics implementation) which
support ",,@" as meaning "map , across the result of the first result, I
might sometimes write:
(defmacro define-protected (op bvl &body forms)
(let ((vars (mapcar #'car bvl))
(types (mapcar #'cadr bvl)))
`(defmacro ,(intern (format nil "PROTECTED-~A" op)) ,vars
`((lambda ,',vars
(when (and ,@',(mapcar #'(lambda (var type) `(typep ,var ',type))
vars types))
,@',forms))
,,@vars))))
I have found ,,@ quite useful in practice, but I've never been clear on
whether it's portable. It had been on my list of things to raise with the
CL Cleanup committee, so thanks for giving me motivation to come up with
a useful test case.
Btw, in case your implementation doesn't support ,,@ -- here are some
test results for comparison:
(macroexpand-1
'(define-protected + ((x fixnum) (y float)) (+ x y)))
=> (DEFMACRO PROTECTED-+ (X Y)
`((LAMBDA (X Y)
(WHEN (AND (TYPEP X 'FIXNUM)
(TYPEP Y 'FLOAT))
(+ X Y)))
,X ,Y))
∂10-Nov-88 1603 Common-Lisp-mailer backquote
Received: from BOOKWORM.SPAR.SLB.COM by SAIL.Stanford.EDU with TCP; 10 Nov 88 16:03:06 PST
Received: from MOTH.SPAR.SLB.COM by BOOKWORM.SPAR.SLB.COM via CHAOS with CHAOS-MAIL id 13519; Thu 10-Nov-88 16:00:43 PST
Date: Thu, 10 Nov 88 16:01 PST
From: Christopher Garrigues <7thSon@SPAR.SLB.COM>
Subject: backquote
To: Don Cohen <donc@vaxa.isi.edu>
cc: common-lisp@sail.stanford.edu, 7thSon@SPAR.SLB.COM
In-Reply-To: <8811101955.AA11298@vaxa.isi.edu>
Message-ID: <19881111000131.2.7THSON@MOTH.SPAR.SLB.COM>
Date: Thu, 10 Nov 88 11:55:40 PST
From: Don Cohen <donc@vaxa.isi.edu>
(defmacro protected-+ (x y)
`(let ((x ,x) (y ,y)) (and (numberp x) (numberp y) (+ x y))))
I prefer this definition:
(defmacro protected-+ (x y &environment env)
(once-only (x y &environment env)
`(and (numberp ,x) (numberp ,y) (+ ,x ,y))))
Using this definition, I then defined the macro for defining protected
forms like this.
(defmacro define-protected (function &rest args)
(let ((name (make-protected-name function))
(let-list (build-let-list args))
(function-call (build-function-call function args)))
`(defmacro ,name
,(mapcar #'cadr args)
(once-only (,@let-list &environment env)
`(and ,,@args ,,function-call)))))
Basically, I simply nested commas within one another. When writing the
outer backquote form, I think of the inner backquote form as if it were
in it's expanded form. Doing this, all you have to do is to make sure
that you're out of a quoted form before you put your other comma in.
this might require typing something like ",'". The only tricky thing is
that I can never remember if I want ",,@" or ",@," and I seem to pick
the wrong one every time.
∂10-Nov-88 1651 Common-Lisp-mailer Re: backquote
Received: from ruffles.nrtc.northrop.com ([128.99.0.44]) by SAIL.Stanford.EDU with TCP; 10 Nov 88 16:50:57 PST
Received: from localhost by RUFFLES.ruffles.nrtc.northrop.com id aa24943;
10 Nov 88 16:46 PST
To: Don Cohen <donc@vaxa.isi.edu>
cc: common-lisp@sail.stanford.edu
Subject: Re: backquote
In-reply-to: Your message of Thu, 10 Nov 88 11:55:40 PST.
<8811101955.AA11298@vaxa.isi.edu>
Reply-To: ssmith@nrtc.northrop.com
Moon-Phase: The moon is a waxing crescent (2 percent of full).
Date: Thu, 10 Nov 88 16:46:32 -0800
From: "Stephen P. Smith" <ssmith@ruffles.nrtc.northrop.com>
Though the other solutions are actually better, here is
the macro exactly as you were trying to get it:
(defmacro define-protected (fcn &rest args)
(let ((targs (mapcar #'cadr args)))
`(defmacro ,(intern (format nil "PROTECTED-~a" fcn)) ,targs
`(let ,(mapcar #'(lambda (var val)
`(,var ,val))
',targs
(list ,@targs))
(and ,',@args (,',fcn ,',@targs))))))
Note that you *must* use the mapcar trick to build the let list; As
you saw, there is no way to pass a "free" comma around.
From your question about the CLtL reference on page 350: It was
also never clear to me without lots of experimentation what
such constructs as ,',@ should do either (or that they were
really allowed).
--Steve
∂10-Nov-88 2222 Common-Lisp-mailer backquote
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 10 Nov 88 22:22:17 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA04475g; Thu, 10 Nov 88 22:19:16 PST
Received: by bhopal id AA12160g; Thu, 10 Nov 88 22:17:57 PST
Date: Thu, 10 Nov 88 22:17:57 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8811110617.AA12160@bhopal>
To: KMP@STONY-BROOK.SCRC.Symbolics.COM
Cc: donc@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: Kent M Pitman's message of Thu, 10 Nov 88 17:55 EST <881110175533.0.KMP@BOBOLINK.SCRC.Symbolics.COM>
Subject: backquote
re: However, in implementations (such as the Symbolics implementation) which
support ",,@" as meaning "map , across the result of the first result, I
might sometimes write: [... a little test case ...]
Lucid Common Lisp supports ",,@" as meaning just exactly what CLtL pages
349-350 describe it to be. And indeed LCL comes up the same results for
your little test case.
Yes, I too have carped a bit about having yet another inscrutable meta-
language for describing backquote [I think that is the source of DonC's
complaint -- it's hard to understand CLtL pp349-50]. But Guy Steele has
always managed to convince me that, for any given example, the rules on
pp349-50 are consistent with the generally perceived notion of how
backquote should work. [By the bye, ask Quux about his favorite
little doubly-nested backquote example; as far as I know, it doesn't
even parse in the Genera reader.]
-- JonL --
∂11-Nov-88 0941 Common-Lisp-mailer Re: backquote
Received: from fs3.cs.rpi.edu by SAIL.Stanford.EDU with TCP; 11 Nov 88 09:41:30 PST
Received: by fs3.cs.rpi.edu (5.54/1.2-RPI-CS-Dept)
id AA01710; Fri, 11 Nov 88 12:37:19 EST
Date: Fri, 11 Nov 88 12:37:18 EST
From: harrisr@turing.cs.rpi.edu (Richard Harris)
Received: by turing.cs.rpi.edu (4.0/1.2-RPI-CS-Dept)
id AA12520; Fri, 11 Nov 88 12:37:18 EST
Message-Id: <8811111737.AA12520@turing.cs.rpi.edu>
To: donc@vaxa.isi.edu
Subject: Re: backquote
Cc: common-lisp@sail.stanford.edu
I wrote some code that does this a while ago. It is quite a bit
more complicated than Barry Margolin's solution, but you might
want to look at it anyway.
Rick Harris
(defmacro once-only (vars &body body) ;from pcl
(let ((gensym-var (gensym))
(run-time-vars (gensym))
(run-time-vals (gensym))
(expand-time-val-forms ()))
`(let* (,run-time-vars
,run-time-vals
(wrapped-body
(let ,(mapcar #'(lambda (var)
`(,var (if (or (symbolp ,var)
(constantp ,var)
(and (consp ,var) (eq (car ,var) 'function)))
,var
(let ((,gensym-var (gensym)))
(push ,gensym-var ,run-time-vars)
(push ,var ,run-time-vals)
,gensym-var))))
vars)
,@body)))
(if (null ,run-time-vars)
wrapped-body
`(let ,(mapcar #'list
(reverse ,run-time-vars)
(reverse ,run-time-vals))
,wrapped-body)))))
(defmacro rest-once-only (rvar &body body)
(let ((var (gensym))
(gensym-var (gensym))
(run-time-vars (gensym))
(run-time-vals (gensym))
(expand-time-val-forms ()))
`(let* (,run-time-vars
,run-time-vals
(wrapped-body
(let ((,rvar (mapcar #'(lambda (,var)
(if (or (symbolp ,var)
(constantp ,var)
(and (consp ,var) (eq (car ,var) 'function)))
,var
(let ((,gensym-var (gensym)))
(push ,gensym-var ,run-time-vars)
(push ,var ,run-time-vals)
,gensym-var)))
,rvar)))
,@body)))
(if (null ,run-time-vars)
wrapped-body
`(let ,(mapcar #'list
(reverse ,run-time-vars)
(reverse ,run-time-vals))
,wrapped-body)))))
(defmacro define-fixnum-macro (name arg-list &body forms)
(let* ((&rest (member '&rest arg-list))
(rest-arg (and &rest (cadr &rest)))
(required-args (if &rest (ldiff arg-list &rest) arg-list)))
(if rest-arg
`(defmacro ,name ,arg-list
(once-only ,required-args
(rest-once-only ,rest-arg
`(and ,@(list ,@(mapcar #'(lambda (arg)
``(typep ,,arg 'fixnum))
required-args))
,@(mapcar #'(lambda (arg)
`(typep ,arg 'fixnum))
,rest-arg)
,(let (,@(mapcar #'(lambda (arg)
`(,arg `(the fixnum ,,arg)))
required-args)
(,rest-arg (mapcar #'(lambda (arg)
`(the fixnum ,arg))
,rest-arg)))
,@forms)))))
`(defmacro ,name ,arg-list
(once-only ,required-args
`(and ,@(list ,@(mapcar #'(lambda (arg)
``(typep ,,arg 'fixnum))
required-args))
,(let ,(mapcar #'(lambda (arg)
`(,arg `(the fixnum ,,arg)))
required-args)
,@forms)))))))
(define-fixnum-macro fixnum-logand (&rest args)
`(logand ,@args))
(define-fixnum-macro fixnum-logior (&rest args)
`(logior ,@args))
(define-fixnum-macro fixnum-logxor (&rest args)
`(logxor ,@args))
(define-fixnum-macro fixnum-1+ (x)
`(1+ ,x))
(define-fixnum-macro fixnum-ash (x n)
`(ash ,x ,n))
∂11-Nov-88 0959 Common-Lisp-mailer backquote
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 11 Nov 88 09:59:24 PST
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 491105; Fri 11-Nov-88 12:58:04 EST
Date: Fri, 11 Nov 88 12:57 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: backquote
To: jonl@lucid.com, KMP@STONY-BROOK.SCRC.Symbolics.COM
cc: donc@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8811110617.AA12160@bhopal>
Message-ID: <19881111175759.2.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Thu, 10 Nov 88 22:17:57 PST
From: Jon L White <jonl@lucid.com>
re: However, in implementations (such as the Symbolics implementation) which
support ",,@" as meaning "map , across the result of the first result, I
might sometimes write: [... a little test case ...]
Lucid Common Lisp supports ",,@" as meaning just exactly what CLtL pages
349-350 describe it to be. And indeed LCL comes up the same results for
your little test case.
Yes, I too have carped a bit about having yet another inscrutable meta-
language for describing backquote [I think that is the source of DonC's
complaint -- it's hard to understand CLtL pp349-50]. But Guy Steele has
always managed to convince me that, for any given example, the rules on
pp349-50 are consistent with the generally perceived notion of how
backquote should work. [By the bye, ask Quux about his favorite
little doubly-nested backquote example; as far as I know, it doesn't
even parse in the Genera reader.]
Could you forward this doubly nested example to me, so that the Genera
reader >will< be able to parse it in future releases?
-- JonL --
∂11-Nov-88 1020 Common-Lisp-mailer backquote
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 11 Nov 88 10:20:46 PST
Posted-Date: Fri, 11 Nov 88 10:18:20 PST
Message-Id: <8811111818.AA01792@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA01792; Fri, 11 Nov 88 10:18:59 PST
To: common-lisp@sail.stanford.edu
Subject: backquote
Date: Fri, 11 Nov 88 10:18:20 PST
From: Don Cohen <donc@vaxa.isi.edu>
First, I was hoping for a clear statement of what nested backquotes
meant. Here's my current theory - the result of experimentation.
I don't see how to interpret CLtL to mean this (innermost backquote
expanded first??), but at least maybe someone in the know can
either confirm my theory (and provide the mapping from CLtL) or
correct it (and still provide the mapping):
When you evaluate a backquote expression (oh, all right, the
result of reading one evaluates as if ...), you throw away the
backquote (we're always evaluating the "outermost" backquote now!),
find all the "matching" commas (which must all be innermost
commas, although not all innermost commas match this backquote!)
and replace them with the results of evaluating them. Leave all
other backquotes and commas (and everything else) alone! Thus
``(a ,s ,',d ,,f `(,g))
-- --
results in evaluation of the underlined expressions, yielding
something like
`(a ,s ,'4 ,7 `(,g))
,@ is just like , except that you throw out an outer pair of parens.
Is that right?
----------------
Next some comments on the "solutions". What they have done is to
change the protected-+ macro from what I would have written
originally into something else - my ((x ,x) (y ,y)) has become a
mapcar. In other words, as long as the expansion has to be
evaluated again, we can replace what we really want with something
else which will later evaluate to the same thing. This works, but
starts to sacrifice some of the clarity which was the reason for
backquote in the first place.
I think it would be a lot easier if you COULD "pass a 'free' comma
around", and more generally, if you could directly express when
each expression should be evaluated, i.e., which backquote it
went with. Here's a "labelled backquote" macro that does this.
Reviews are welcome. I describe it as a regular macro, not a
readmacro. I wonder whether that's important. Perhaps backquote
could be extended in this direction.
----------------
(LBQ <label> ...) finds all occurrences of |,| (|,@|) which
are followed by <label>, throws out the |,| and label and replaces
the following expression with its value.
(defmacro define-protected (function &rest args)
(LBQ outer defmacro |,| outer (MAKE-PROTECTED-NAME function)
|,| outer (mapcar #'cadr args)
(LBQ inner let |,| outer (BUILD-LET-LIST args)
(and |,@| outer args
|,| outer (BUILD-FUNCTION-CALL function args)))))
where BUILD-LET-LIST produces a list of the form
((x |,| inner x) (y |,| inner y)):
Note that with backquote I couldn't have removed this into another
function - sort of reminds you of lexical scoping, huh?
(defun BUILD-LET-LIST (args)
(mapcar #'(lambda (arg) (list (cadr arg) '|,| 'inner (cadr arg))) args))
(defun BUILD-FUNCTION-CALL (function args)
(cons function (mapcar #'cadr args)))
(macroexpand-1 '(define-protected + (numberp x) (numberp y)))
=>
(DEFMACRO PROTECTED-+
(X Y)
(LBQ INNER LET
((X |,| INNER X) (Y |,| INNER Y))
(AND (NUMBERP X) (NUMBERP Y) (+ X Y))))
∂11-Nov-88 1804 Common-Lisp-mailer Re: backquote
Received: from argus.Stanford.EDU by SAIL.Stanford.EDU with TCP; 11 Nov 88 18:04:22 PST
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by argus.Stanford.EDU with TCP; Fri, 11 Nov 88 17:57:40 PST
Received: from F.ILA.Dialnet.Symbolics.COM (FUJI.ILA.Dialnet.Symbolics.COM) by Riverside.SCRC.Symbolics.COM via DIAL with SMTP id 293976; 11 Nov 88 21:01:28 EST
Date: Fri, 11 Nov 88 19:08 EST
From: Robert W. Kerns <RWK@f.ila.dialnet.symbolics.com>
Subject: Re: backquote
To: ssmith@nrtc.northrop.com, donc@vaxa.isi.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: The message of 10 Nov 88 19:46 EST from Stephen P. Smith <ssmith@ruffles.nrtc.northrop.com>
Message-Id: <19881112000850.2.RWK@F.ILA.Dialnet.Symbolics.COM>
Date: Thu, 10 Nov 88 16:46:32 -0800
From: "Stephen P. Smith" <ssmith@ruffles.nrtc.northrop.com>
From your question about the CLtL reference on page 350: It was
also never clear to me without lots of experimentation what
such constructs as ,',@ should do either (or that they were
really allowed).
Well, ,',@X is basically nonsense, unless you KNOW that X is exactly
one element long. Otherwise you're passing the wrong number of
arguments to the QUOTE special form. If you thin kyou want ,',@, you
probably want ,@',X.
One way to look at ,@',X and ,',X is that these evaluate the X from the
OUTER backquote's context. Remember, the outer one is actually BUILDING
the inner one. The inner one being built is then "commafying" a quoted
list.
∂13-Nov-88 1538 Common-Lisp-mailer backquote
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 13 Nov 88 15:38:05 PST
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 491650; 13 Nov 88 18:34:25 EST
Date: Sun, 13 Nov 88 18:34 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: backquote
To: donc@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8811111818.AA01792@vaxa.isi.edu>
Message-ID: <19881113233411.3.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Fri, 11 Nov 88 10:18:20 PST
From: Don Cohen <donc@vaxa.isi.edu>
First, I was hoping for a clear statement of what nested backquotes
meant. Here's my current theory - the result of experimentation.
I don't see how to interpret CLtL to mean this (innermost backquote
expanded first??), but at least maybe someone in the know can
either confirm my theory (and provide the mapping from CLtL) or
correct it (and still provide the mapping):
First, you should distinguish between the two cases of nested backquotes
with an intervening comma, and nested backquotes without an intervening
comma. The former case is unambigously specified by CLtL. The latter
isn't (the outer backquote will capture the intermediate state of the
computation of the inner backquote.)
Yours is an example of the latter case.
When you evaluate a backquote expression (oh, all right, the
result of reading one evaluates as if ...), you throw away the
backquote (we're always evaluating the "outermost" backquote now!),
find all the "matching" commas
You can't do this without expanding the inner nested backquotes first.
(which must all be innermost
commas, although not all innermost commas match this backquote!)
and replace them with the results of evaluating them. Leave all
other backquotes and commas (and everything else) alone! Thus
``(a ,s ,',d ,,f `(,g))
-- --
results in evaluation of the underlined expressions, yielding
something like
`(a ,s ,'4 ,7 `(,g))
,@ is just like , except that you throw out an outer pair of parens.
Is that right?
No (it's not outright "wrong"). It is sort of backwards.
CLtL states "If the backquote syntax is nested, the innermost backquoted
form should be expanded first."
This means that you can't start stripping commas until all inner
backquotes have been expanded. At any given level of expansion you
use the outtermost comma first.
The result of expanding a backquote is only defined after evaluation, so
the exact details of the list structure returned by `` will vary from
implementation to implementation, however, the result of evaluating the
value of a ``<form> should be consistent.
In your example what's happening is something like this:
Using the transformation rules at the top of page 350 this means that
the interpretation of your example proceeds as follows:
(forms like <...>, inside angle brackets are uninterpreted expressions
inside a backquote. Note that there's an implicit backquote before a <.
You cannot intrepet the body of a <...> unless there are no <>'s inside
it.)
``(a ,s ,',d ,,f `(,g))
<`(a ,s ,',d ,,f `(,g))>
;; now we have a problem. The inner backquote is going to produce a
;; form that "when evaluated will ...", but the outer backquote is
;; telling us not to actually evaluate that form. So we exposing the
;; innards of whichever reader we happen to be using.
;; For the sake of pedagogy we choose a very simple backquote
;; implementation. We use bq-list instead of
;; list so that the pretty printer will be able to print out these lists
;; in backquote syntax.
;; So the next step is:
<(bq-list <a> <,s> <,',d> <,,f> <`(,g)>)>
<(bq-list 'a <,s> <,',d> <,,f> <`(,g)>)>
<(bq-list 'a s <,',d> <,,f> <`(,g)>)>
;; now, the rules tell us how to take off the outermost ","
<(bq-list 'a s ',d <,,f> <`(,g)>)>
;; ditto
<(bq-list 'a s ',d ,f <`(,g)>)>
<(bq-list 'a s ',d ,f (bq-list <,g>))>
<(bq-list 'a s ',d ,f (bq-list g))>
;; now we can interpret <(bq-list ...)> relative to the outer backquote
(bq-list <bq-list> <'a> <s> <',d> <,f> <(bq-list g)>)
;; the interpretation of <bq-list>, <'a>, and <s> are done in one step here
;; because I'm getting bored...
(bq-list 'bq-list ''a 's <',d> <,f> <(bq-list g)>)
;; this should help illustrate what >really< happened to <'a> in all of
;; its boring steps.
(bq-list 'bq-list ''a 's (list 'quote <,d>) <,f> <(bq-list g)>)
(bq-list 'bq-list ''a 's (list 'quote d) <,f> <(bq-list g)>)
(bq-list 'bq-list ''a 's (list 'quote d) f <(bq-list g)>)
(bq-list 'bq-list ''a 's (list 'quote d) f (list 'bq-list 'g))
Say that BQ-LIST acts exactly like LIST, except that the pretty printer
knows how to print a list whose car is BQ-LIST by printing a leading
backquote, and stripping one quote from each elt of the list, and if
there's no quote to strip, inserting a comma.
Then the result of the reading and evaluating your example (if D is 4
and F is 7)
read of ``(a ,s ,',d ,,f `(,g))
=> (bq-list 'bq-list ''a 's (list 'quote d) f (list 'bq-list 'g))
Eval of that
=> (bq-list 'a s '4 7 (bq-list g))
Which would be printed
`(a ,s 4 7 `(,g))
So the illusion is that it is matching inner-most comma's to the
outermost backquote, but in fact it is behaving roughly the way I
describe, and CLtL defines. (I wasn't very careful about this, so I
might have made some mistakes - it's an awfully baroque transformation).
A more common case is where the nested backquote is inside a comma, so
that the backquote implementation isn't exposed in the final result.
∂13-Nov-88 2008 Common-Lisp-mailer backquote
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 13 Nov 88 20:08:42 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA05685g; Sun, 13 Nov 88 20:06:13 PST
Received: by bhopal id AA20070g; Sun, 13 Nov 88 20:04:56 PST
Date: Sun, 13 Nov 88 20:04:56 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8811140404.AA20070@bhopal>
To: Greenwald@STONY-BROOK.SCRC.Symbolics.COM
Cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, donc@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Fri, 11 Nov 88 12:57 EST <19881111175759.2.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: backquote
re: Could you forward this doubly nested example to me, so that the Genera
reader >will< be able to parse it in future releases?
I think it is ``(,@,@x). Believe it or not, one can "crank" the rules
of CLtL p349-50 to come up with a meaning for it. Lucid, Xerox, and
VAXLISP get it "right" according to that meaning. Several others generate
a read-time error (which is what I think Symbolics 7.0 does). I've seen
some that parse it without error but subsquently generate wrong code.
As to whether this was ever used in naturally occurring code -- I dunno.
Ask QUUX (Guy L Steele).
-- JonL --
P.S.: When trying to work out an example using the rules of CLtL p340-50,
it's important to remember that the square-brackets are part of the
syntax of that crufty litle production-rule language. They are not
meta-meta-syntax.
∂14-Nov-88 0007 Common-Lisp-mailer backquote
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 14 Nov 88 00:07:15 PST
Return-Path: <barmar@Think.COM>
Received: from kulla.think.com by Think.COM; Mon, 14 Nov 88 02:27:39 EST
Received: by kulla.think.com; Mon, 14 Nov 88 02:43:25 EST
Date: Mon, 14 Nov 88 02:43:25 EST
From: barmar@Think.COM
Message-Id: <8811140743.AA22690@kulla.think.com>
To: jonl@lucid.com
Cc: Greenwald@stony-brook.scrc.symbolics.com,
KMP@stony-brook.scrc.symbolics.com, donc@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-Reply-To: Jon L White's message of Sun, 13 Nov 88 20:04:56 PST <8811140404.AA20070@bhopal>
Subject: backquote
Specifically Re: ``(,@,@x)
It does still get a read-time error on Genera 7.2. I also tried some
variants. ``(,@,@x a) seems to work. ``(a ,@,@x) doesn't get an
error, but I think it gets the wrong result.
barmar
∂14-Nov-88 0843 Common-Lisp-mailer backquote
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Nov 88 08:43:14 PST
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 491891; Mon 14-Nov-88 11:41:01 EST
Date: Mon, 14 Nov 88 11:40 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: backquote
To: jonl@lucid.com, Greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: KMP@STONY-BROOK.SCRC.Symbolics.COM, donc@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: <8811140404.AA20070@bhopal>
Message-ID: <19881114164032.1.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Sun, 13 Nov 88 20:04:56 PST
From: Jon L White <jonl@lucid.com>
re: Could you forward this doubly nested example to me, so that the Genera
reader >will< be able to parse it in future releases?
I think it is ``(,@,@x). Believe it or not, one can "crank" the rules
of CLtL p349-50 to come up with a meaning for it.
Once you mention the example, it's not hard to believe at all.
The bug in the Symbolics implementation is that it tries to optimize
`(,@<form>) to just be <form>. This isn't legal when you are inside
another backquote, and <form> might have a ",." or a ",@" that might
have to be further expanded.
I've submitted a patch.
Lucid, Xerox, and
VAXLISP get it "right" according to that meaning. Several others generate
a read-time error (which is what I think Symbolics 7.0 does). I've seen
some that parse it without error but subsquently generate wrong code.
As to whether this was ever used in naturally occurring code -- I dunno.
Ask QUUX (Guy L Steele).
-- JonL --
P.S.: When trying to work out an example using the rules of CLtL p340-50,
it's important to remember that the square-brackets are part of the
syntax of that crufty litle production-rule language. They are not
meta-meta-syntax.
Right.
∂14-Nov-88 0918 Common-Lisp-mailer nested backquotes
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 14 Nov 88 09:16:59 PST
Posted-Date: Mon, 14 Nov 88 09:11:39 PST
Message-Id: <8811141711.AA04256@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA04256; Mon, 14 Nov 88 09:11:42 PST
To: greenwald@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
Subject: nested backquotes
Date: Mon, 14 Nov 88 09:11:39 PST
From: Don Cohen <donc@vaxa.isi.edu>
I think I understand your description (I think you left out a quote or
two in the last element). Furthermore, I strongly suspect (but have
not yet proven) that it is equivalent to mine. If so, my explanation
seems easier to understand. The only problem was that you evidently
did not understand what "matching" meant. It was very simple and did
NOT require expanding the inner backquotes. Let me rephrase the model
and see if you agree that it gives the same results as yours.
Pretend that comma (comma@) reads like quote - ,x = (COMMA x) except
that an expression may not be in the scope of more commas than backquotes.
Similarly, suppose that backquote reads as the symbol BACKQUOTE consed
onto the next read. So ``(a ,s ,',d ,,f `(,g)) reads as
(BACKQUOTE BACKQUOTE a (COMMA s) (COMMA (QUOTE (COMMA d)))
(COMMA (COMMA f)) (BACKQUOTE ((COMMA g))))
Now in order to evaluate that expression we find all forms that are
in the scope of as many COMMAs as BACKQUOTEs. We discard the leading
BACKQUOTE and replace such expressions (along with the matching COMMAs)
with their values. In this case, the d and f are in the scope of 2 of
each. The result is
(BACKQUOTE a (COMMA s) (COMMA (QUOTE 4)) (COMMA 7) (BACKQUOTE ((COMMA g))))
Evaluating this would similarly give something like
(a 3 4 7 (BACKQUOTE ((COMMA g))))
If you don't believe this model is equivalent please send me a
counterexample. (The only thing I can see won't work is if something
EVALUATES to a list containing the symbols BACKQUOTE or COMMA, and I
think we can pretend that's impossible, even though it's precisely what
I really WANTED to do!)
∂14-Nov-88 1027 Common-Lisp-mailer nested backquotes
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 14 Nov 88 10:27:20 PST
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 492023; Mon 14-Nov-88 13:27:23 EST
Date: Mon, 14 Nov 88 13:27 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: nested backquotes
To: donc@vaxa.isi.edu, greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811141711.AA04256@vaxa.isi.edu>
Message-ID: <19881114182707.6.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Date: Mon, 14 Nov 88 09:11:39 PST
From: Don Cohen <donc@vaxa.isi.edu>
I think I understand your description (I think you left out a quote or
two in the last element). Furthermore, I strongly suspect (but have
not yet proven) that it is equivalent to mine. If so, my explanation
seems easier to understand.
You said:
"I don't see how to interpret CLtL to mean this (innermost backquote
expanded first??)"
I was just explaining the behavior of readers (that you determined
"experimentally") did conform to CLtL. I thought you decided that CLtL
did not define the case of nested backquotes unambiguously. I was just
pointing out that CLtL's rules defining the interpretation of nested
backquote cases *are* well-defined. I don't claim that the rules are an
example of pedagogic clarity, or that your explication isn't easier to
understand, I was just showing you how CLtL's rules work.
The rule (in concise form) is: Expand the innermost backquote first,
always using the outermost comma.
The rule itself is simple. In more complicated situations the
productions are ugly, taking many steps, and your model probably
describes the behavior more clearly. I don't know. I haven't tried to
prove that your model is equivalent to CLtL's rule, but intuitively they
seem equivalent.
If you understand CLtL's rule now, then you can use your model with more
confidence, since your original problem seemed to be that you didn't
know how to derive the behavior of readers from the specification in
CLtL.
If you can prove that your model is equivalent, and if it is accepted
that your model is a clearer and cleaner explanation, then your model
should probably be included in a future backquote specification as a
useful guideline.
The only problem was that you evidently
did not understand what "matching" meant. It was very simple and did
NOT require expanding the inner backquotes. Let me rephrase the model
and see if you agree that it gives the same results as yours.
Pretend that comma (comma@) reads like quote - ,x = (COMMA x) except
that an expression may not be in the scope of more commas than backquotes.
Similarly, suppose that backquote reads as the symbol BACKQUOTE consed
onto the next read. So ``(a ,s ,',d ,,f `(,g)) reads as
(BACKQUOTE BACKQUOTE a (COMMA s) (COMMA (QUOTE (COMMA d)))
(COMMA (COMMA f)) (BACKQUOTE ((COMMA g))))
Now in order to evaluate that expression we find all forms that are
in the scope of as many COMMAs as BACKQUOTEs. We discard the leading
BACKQUOTE and replace such expressions (along with the matching COMMAs)
with their values. In this case, the d and f are in the scope of 2 of
each. The result is
(BACKQUOTE a (COMMA s) (COMMA (QUOTE 4)) (COMMA 7) (BACKQUOTE ((COMMA g))))
Evaluating this would similarly give something like
(a 3 4 7 (BACKQUOTE ((COMMA g))))
If you don't believe this model is equivalent please send me a
counterexample. (The only thing I can see won't work is if something
EVALUATES to a list containing the symbols BACKQUOTE or COMMA,
The evaluation does not occur at read-time, unless there's a #,, but
then you can't pass ","'s up, so I don't think this is relevant.
and I
think we can pretend that's impossible, even though it's precisely what
I really WANTED to do!)
∂14-Nov-88 1350 Common-Lisp-mailer nested backquotes
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 14 Nov 88 13:50:22 PST
Received: from fafnir.think.com by Think.COM; Mon, 14 Nov 88 16:27:03 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Mon, 14 Nov 88 16:46:19 EST
Received: from joplin.think.com by verdi.think.com; Mon, 14 Nov 88 16:46:18 EST
Received: by joplin.think.com; Mon, 14 Nov 88 16:46:15 EST
Date: Mon, 14 Nov 88 16:46:15 EST
From: gls@Think.COM
Message-Id: <8811142146.AA29789@joplin.think.com>
To: donc@vaxa.isi.edu
Cc: greenwald@stony-brook.scrc.symbolics.com, common-lisp@sail.stanford.edu
In-Reply-To: Don Cohen's message of Mon, 14 Nov 88 09:11:39 PST <8811141711.AA04256@vaxa.isi.edu>
Subject: nested backquotes
Posted-Date: Mon, 14 Nov 88 09:11:39 PST
Date: Mon, 14 Nov 88 09:11:39 PST
From: Don Cohen <donc@vaxa.isi.edu>
I think I understand your description (I think you left out a quote or
two in the last element). Furthermore, I strongly suspect (but have
not yet proven) that it is equivalent to mine. If so, my explanation
seems easier to understand. The only problem was that you evidently
did not understand what "matching" meant. It was very simple and did
NOT require expanding the inner backquotes. Let me rephrase the model
and see if you agree that it gives the same results as yours.
Pretend that comma (comma@) reads like quote - ,x = (COMMA x) except
that an expression may not be in the scope of more commas than backquotes.
Similarly, suppose that backquote reads as the symbol BACKQUOTE consed
onto the next read. So ``(a ,s ,',d ,,f `(,g)) reads as
(BACKQUOTE BACKQUOTE a (COMMA s) (COMMA (QUOTE (COMMA d)))
(COMMA (COMMA f)) (BACKQUOTE ((COMMA g))))
Now in order to evaluate that expression we find all forms that are
in the scope of as many COMMAs as BACKQUOTEs. We discard the leading
BACKQUOTE and replace such expressions (along with the matching COMMAs)
with their values. In this case, the d and f are in the scope of 2 of
each. The result is
(BACKQUOTE a (COMMA s) (COMMA (QUOTE 4)) (COMMA 7) (BACKQUOTE ((COMMA g))))
Evaluating this would similarly give something like
(a 3 4 7 (BACKQUOTE ((COMMA g))))
If you don't believe this model is equivalent please send me a
counterexample. (The only thing I can see won't work is if something
EVALUATES to a list containing the symbols BACKQUOTE or COMMA, and I
think we can pretend that's impossible, even though it's precisely what
I really WANTED to do!)
I believe that this model can be made to work, but you need additional
rules to explain what happens when ``(a ,,@f) expands to
(BACKQUOTE BACKQUOTE a (COMMA (COMMA@ f))). At the very least you
must allow for COMMA having more than one subform.
--Guy
∂14-Nov-88 1438 Common-Lisp-mailer nested backquotes
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 14 Nov 88 14:37:38 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00533g; Mon, 14 Nov 88 14:35:51 PST
Received: by bhopal id AA21716g; Mon, 14 Nov 88 14:34:27 PST
Date: Mon, 14 Nov 88 14:34:27 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8811142234.AA21716@bhopal>
To: donc@vaxa.isi.edu
Cc: greenwald@stony-brook.scrc.symbolics.com, common-lisp@sail.stanford.edu
In-Reply-To: Don Cohen's message of Mon, 14 Nov 88 09:11:39 PST <8811141711.AA04256@vaxa.isi.edu>
Subject: nested backquotes
The problem with "explanations" of backquote is that they tend to be
much longer than the "production rules" on CLtL p.349-50. Of course,
the problem with CLtL here is opacity.
The only rule I ever remember, and found quite useful, is:
"When in doubt, Hack it out."
In short, after implementing the rules of CLtL rigorously, then I just
try reading (and sometimes macroexpanding) several variants of the form
I'm trying to build up. Apart from ultimately matching the depth of
nesting for commas and backquotes, I just try a lot of variations of
",," ",'," ",,@" etc. You'd be surprised how useful the "hack it out"
rule is! especially in leanring when ",'," must be used instead of ",,".
One program I was writing once wound up 6 levels deep; the "hack it out"
rule wasn't very helpful here, because the expression was too large.
Ultimately, I wound up finding a "break point", and pulled out some of
the code into a separate function, much as you originally did in your
first example with BUILD-LET-LIST. At that point it was 4 levels and 2
levels -- much more managable.
-- JonL --
∂14-Nov-88 1817 Common-Lisp-mailer Re: nested backquotes
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 14 Nov 88 18:17:11 PST
Posted-Date: Mon, 14 Nov 88 15:29:34 PST
Message-Id: <8811142330.AA12027@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA12027; Mon, 14 Nov 88 15:30:27 PST
To: gls@think.com
Cc: greenwald@stony-brook.scrc.symbolics.com, common-lisp@sail.stanford.edu
Subject: Re: nested backquotes
In-Reply-To: Your message of Mon, 14 Nov 88 16:46:15 -0500.
<8811142146.AA29789@joplin.think.com>
Date: Mon, 14 Nov 88 15:29:34 PST
From: Don Cohen <donc@vaxa.isi.edu>
Now there's a good point. What does that mean anyhow?
Please try to justify your answer.
∂16-Nov-88 1003 Common-Lisp-mailer nested backquotes
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Nov 88 10:03:27 PST
Received: from fafnir.think.com by Think.COM; Wed, 16 Nov 88 12:38:56 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 16 Nov 88 13:00:27 EST
Received: from joplin.think.com by verdi.think.com; Wed, 16 Nov 88 13:00:26 EST
Received: by joplin.think.com; Wed, 16 Nov 88 13:00:23 EST
Date: Wed, 16 Nov 88 13:00:23 EST
From: gls@Think.COM
Message-Id: <8811161800.AA00323@joplin.think.com>
To: donc@vaxa.isi.edu
Cc: gls@Think.COM, greenwald@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
In-Reply-To: Don Cohen's message of Mon, 14 Nov 88 15:29:34 PST <8811142330.AA12027@vaxa.isi.edu>
Subject: nested backquotes
Posted-Date: Mon, 14 Nov 88 15:29:34 PST
Date: Mon, 14 Nov 88 15:29:34 PST
From: Don Cohen <donc@vaxa.isi.edu>
Now there's a good point. What does that mean anyhow?
Please try to justify your answer.
Look, I've already provided a model. You're trying to produce a new
model. The task is to prove that they are equivalent; in other words,
that for any backquoted expression the two models provide equivalent
interpretations. (Alternatively, where the two models produce
inequivalent results, you need to argue that the first model is bogus.
That would be a really interesting result!)
Now, for some backquoted expressions your model produces intermediate
results in which COMMA has more than one argument form. So you need
either to provide an interpretation in your model for such intermediate
results (i.e., new productions), or to argue that backquoted expressions
that produce such intermediate results are not meaningful.
--Guy
∂16-Nov-88 1158 Common-Lisp-mailer Re: nested backquotes
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 16 Nov 88 11:58:11 PST
Posted-Date: Wed, 16 Nov 88 11:54:30 PST
Message-Id: <8811161954.AA03714@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA03714; Wed, 16 Nov 88 11:54:49 PST
To: gls@think.com
Cc: greenwald@stony-brook.scrc.symbolics.com, common-lisp@sail.stanford.edu
Subject: Re: nested backquotes
In-Reply-To: Your message of Wed, 16 Nov 88 13:00:23 -0500.
<8811161800.AA00323@joplin.think.com>
Date: Wed, 16 Nov 88 11:54:30 PST
From: Don Cohen <donc@vaxa.isi.edu>
I agree that my model does not handle this case.
I had a hard time seeing how your model does.
The Greenwald explanation gives me a hint of how to
interpret CLtL. I think what I was missing was the
idea that [,,x] would be interpreted by treating the
inner comma as part of the form in the outer comma,
e.g., [(comma (comma x))] => (list (comma x)).
Just to test my new interpretation, does this look right?
(setq x '(y z))
``(,@,@x) =>
`(append [,@,@x] 'nil) =>
`(append ,@x 'nil) =>
(append [append] [,@x] ['nil] nil) =>
(append (list 'append) x (list ''nil) nil)
which evaluates to (APPEND Y Z 'NIL)
∂16-Nov-88 1241 Common-Lisp-mailer Remove amellor@bbn.com please
Received: from CASABLANCA.BBN.COM by SAIL.Stanford.EDU with TCP; 16 Nov 88 12:41:45 PST
Date: Wed, 16 Nov 88 15:30:57 EST
From: Art Mellor <amellor@CASABLANCA.BBN.COM>
To: common-lisp@sail.stanford.edu
Subject: Remove amellor@bbn.com please
see subject
∂16-Nov-88 1500 Common-Lisp-mailer nested backquotes
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 16 Nov 88 15:00:23 PST
Received: from fafnir.think.com by Think.COM; Wed, 16 Nov 88 17:35:05 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Wed, 16 Nov 88 17:56:39 EST
Received: from joplin.think.com by verdi.think.com; Wed, 16 Nov 88 17:56:38 EST
Received: by joplin.think.com; Wed, 16 Nov 88 17:56:34 EST
Date: Wed, 16 Nov 88 17:56:34 EST
From: gls@Think.COM
Message-Id: <8811162256.AA00511@joplin.think.com>
To: donc@vaxa.isi.edu
Cc: gls@Think.COM, greenwald@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
In-Reply-To: Don Cohen's message of Wed, 16 Nov 88 11:54:30 PST <8811161954.AA03714@vaxa.isi.edu>
Subject: nested backquotes
Posted-Date: Wed, 16 Nov 88 11:54:30 PST
Date: Wed, 16 Nov 88 11:54:30 PST
From: Don Cohen <donc@vaxa.isi.edu>
I agree that my model does not handle this case.
I had a hard time seeing how your model does.
The Greenwald explanation gives me a hint of how to
interpret CLtL. I think what I was missing was the
idea that [,,x] would be interpreted by treating the
inner comma as part of the form in the outer comma,
e.g., [(comma (comma x))] => (list (comma x)).
Just to test my new interpretation, does this look right?
(setq x '(y z))
``(,@,@x) =>
`(append [,@,@x] 'nil) =>
`(append ,@x 'nil) =>
(append [append] [,@x] ['nil] nil) =>
(append (list 'append) x (list ''nil) nil)
which evaluates to (APPEND Y Z 'NIL)
Right!
∂18-Nov-88 0233 Common-Lisp-mailer backquote
Received: from NSS.Cs.Ucl.AC.UK by SAIL.Stanford.EDU with TCP; 18 Nov 88 02:33:15 PST
Received: from maths.bath.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP
id aa01665; 15 Nov 88 13:02 GMT
Received: from xenakis by mordell.maths.bath.AC.UK id aa12898;
15 Nov 88 11:41 GMT
To: Greenwald@scrc-stony-brook.arpa
CC: jonl%lucid.com@NSS.Cs.Ucl.AC.UK, Greenwald@scrc-stony-brook.arpa,
KMP@scrc-stony-brook.arpa, donc@vaxa.isi.edu,
common-lisp@sail.stanford.edu
In-reply-to: Michael Greenwald's message of Mon, 14 Nov 88 11:40 EST <19881114164032.1.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: backquote
Date: Tue, 15 Nov 88 11:40:26 GMT
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
OK, I have tried to read the backquote material. What is the correct
meaning of ``(,@,@x) please?
==John
∂18-Nov-88 1041 Common-Lisp-mailer backquote
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 18 Nov 88 10:41:07 PST
Received: from fafnir.think.com by Think.COM; Fri, 18 Nov 88 13:12:41 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 18 Nov 88 13:36:17 EST
Received: from joplin.think.com by verdi.think.com; Fri, 18 Nov 88 13:36:16 EST
Received: by joplin.think.com; Fri, 18 Nov 88 13:36:12 EST
Date: Fri, 18 Nov 88 13:36:12 EST
From: gls@Think.COM
Message-Id: <8811181836.AA01536@joplin.think.com>
To: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Cc: Greenwald@scrc-stony-brook.arpa, jonl%lucid.com@NSS.Cs.Ucl.AC.UK,
Greenwald@scrc-stony-brook.arpa, KMP@scrc-stony-brook.arpa,
donc@vaxa.isi.edu, common-lisp@sail.stanford.edu
In-Reply-To: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK's message of Tue, 15 Nov 88 11:40:26 GMT <8811181010.AA11573@Think.COM>
Subject: backquote
Date: Tue, 15 Nov 88 11:40:26 GMT
From: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
Sender: jpff%maths.bath.ac.uk@NSS.Cs.Ucl.AC.UK
OK, I have tried to read the backquote material. What is the correct
meaning of ``(,@,@x) please?
==John
Here is a concise, if not precise, description:
`(,@q) means "I evaluate to a list with the list named q spliced in"
``(,@,@x) means "I evaluate to an expression that, when evaluated,
will make a list with the values of lots of
list spliced in, where x is a list of forms
that will evaluate to those lists"
and, if you can stomach it,
```(,@,@,@x) means "I evaluate to an expression that, when evaluated,
produces an expression that, when evaluated,
will make a list with the values of lots of
list spliced in, where x is a list of forms,
each of which will evaluate to a form that
when evaluated will produce a list for splicing"
Got that?
--Guy
∂28-Nov-88 1745 Common-Lisp-mailer inconsistency in backquote spec?
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 28 Nov 88 17:45:07 PST
Received: from SWALLOW.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 498891; Mon 28-Nov-88 20:45:07 EST
Date: Mon, 28 Nov 88 20:44 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
To: common-lisp@sail.stanford.edu
Message-ID: <19881129014452.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
(setq d '(a . b))
'`(,@d) => `(a . b) or `(a)?
If you read CLtL, pg 350. it says that it's equivalent to
`(,@d . nil)
which is
(append [,@d] 'nil)
(append d 'nil)
which suggests the correct value is `(a).
If you look at most implementations, and at the examples on pg 351, then
you'd think it should be `(a . b)
However, the example at the bottom of page 350 suggest alternate
"legitimate interpretations" continued on the top of pg 351. All of
them except the first, consider (APPEND .... D NIL) to be equivalent to
(APPEND ... D), which isn't true if D can be a dotted list.
I tried Ibuki, Franz, Lucid, and Genera.
In all of them evaluating '`(,@'(a . b)) => `(a . b).
In Ibuki and Lucid '`(,@'(a . b) ,@nil) => '([bq-]append '(a . b) nil)
while in Genera and Franz '`(,@'(a . b) ,@nil) => `(a . b)
Are dotted lists not allowed as values of D? Is the spec on pg 350
correct, and the examples on pg. 351 incorrect?
I tend to believe the latter. In which case, all of the readers I tried
are incorrect. I'm not going to change the Genera reader, though, until
I hear from this list, in case my brain is just wedged. Can someone
either deconfuse or support me?
∂29-Nov-88 0014 Common-Lisp-mailer inconsistency in backquote spec?
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 29 Nov 88 00:14:07 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01440g; Tue, 29 Nov 88 00:12:00 PST
Received: by bhopal id AA00624g; Tue, 29 Nov 88 00:10:53 PST
Date: Tue, 29 Nov 88 00:10:53 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8811290810.AA00624@bhopal>
To: Greenwald@STONY-BROOK.SCRC.Symbolics.COM
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Mon, 28 Nov 88 20:44 EST <19881129014452.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
re: However, the example at the bottom of page 350 suggest alternate
"legitimate interpretations" continued on the top of pg 351. All of
them except the first, consider (APPEND .... D NIL) to be equivalent to
(APPEND ... D), which isn't true if D can be a dotted list.
[This may be a question about "standard lists" more than about backquote.]
I remember some sleeping dogs about APPEND -- all arguments except the last
are required to be "lists". Since APPEND has to copy the next to last
argument, it must cdr down to the last cell of the list; thus it should
complain about non-standard lists. [The permission to use non-standard
lists is primarily when the operation of interest will not cdr down to
the last cell, and hence it would be a moot question.]
Long long ago, Lucid made the decision to make non-standard lists acceptable
just about everwhere that "lists" are. Thus in Lucid Common Lisp:
(APPEND '(A . B) NIL) ==> (A)
(APPEND NIL '(A . B)) ==> (A . B)
I can't say that I am fully happy with this; but it's very low on my
list of worries today.
-- JonL --
∂29-Nov-88 0813 Common-Lisp-mailer Common Lisp for SUNS
Received: from red.ipsa.dnd.ca by SAIL.Stanford.EDU with TCP; 29 Nov 88 08:13:45 PST
Received: by red.ipsa.dnd.ca; (5.54/4.7)
id AA01479; Tue, 29 Nov 88 11:14:29 EST
Date: Tue, 29 Nov 88 11:14:29 EST
From: bill@red.ipsa.dnd.ca (Bill Pase)
Message-Id: <8811291614.AA01479@red.ipsa.dnd.ca>
To: common-lisp@sail.stanford.edu
Subject: Common Lisp for SUNS
Can anyone tell me about their experiences with Common Lisp systems
for Sun Computers. I know of four implementations, Kyoto Common Lisp,
Lucid Common Lisp, Sun Common Lisp, and Allegro Common Lisp.
I'm especially interested in the run time performance, since we hope
to use one of these lisps as a delivery vehicle for code developed on
Symbolics Computers. (It'd be real nice if the lisp benchmark data
was available?) Of course if anyone has experiences with using these
systems as a development environment, I'd not mind hearing it.
/bill
∂29-Nov-88 0906 Common-Lisp-mailer Common Lisp for SUNS
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 29 Nov 88 09:04:27 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Tue, 29 Nov 88 12:02:03 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Tue, 29 Nov 88 12:02:57 EST
Date: Tue, 29 Nov 88 12:03 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Common Lisp for SUNS
To: Bill Pase <bill@red.ipsa.dnd.ca>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811291614.AA01479@red.ipsa.dnd.ca>
Message-Id: <19881129170307.7.BARMAR@OCCAM.THINK.COM>
Date: Tue, 29 Nov 88 11:14:29 EST
From: bill@red.ipsa.dnd.ca (Bill Pase)
Can anyone tell me about their experiences with Common Lisp systems
for Sun Computers. I know of four implementations, Kyoto Common Lisp,
Lucid Common Lisp, Sun Common Lisp, and Allegro Common Lisp.
Sun Common Lisp currently is Lucid Common Lisp. There were rumors last
year that they would be switching to Franz (who makes Allegro CL), but
this doesn't appear to have happened.
Kyoto CL is not generally considered a high-performance Lisp. Its major
feature is its portability, since it is written mostly in C and its
compiler uses C as the intermediate language. It is also well-known for
being very faithful to CLtL, implementing all and only what the book
says.
barmar
∂29-Nov-88 0937 Common-Lisp-mailer inconsistency in backquote spec?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 29 Nov 88 09:36:59 PST
Received: from fafnir.think.com by Think.COM; Tue, 29 Nov 88 12:34:44 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Tue, 29 Nov 88 12:35:41 EST
Received: from joplin.think.com by verdi.think.com; Tue, 29 Nov 88 12:34:10 EST
Received: by joplin.think.com; Tue, 29 Nov 88 12:35:36 EST
Date: Tue, 29 Nov 88 12:35:36 EST
From: gls@Think.COM
Message-Id: <8811291735.AA00711@joplin.think.com>
To: Greenwald@stony-brook.scrc.symbolics.com
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Mon, 28 Nov 88 20:44 EST <19881129014452.7.GREENWALD@SWALLOW.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
Date: Mon, 28 Nov 88 20:44 EST
From: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
(setq d '(a . b))
'`(,@d) => `(a . b) or `(a)?
If you read CLtL, pg 350. it says that it's equivalent to
`(,@d . nil)
which is
(append [,@d] 'nil)
(append d 'nil)
which suggests the correct value is `(a).
...
Are dotted lists not allowed as values of D? Is the spec on pg 350
correct, and the examples on pg. 351 incorrect?
I tend to believe the latter. In which case, all of the readers I tried
are incorrect. I'm not going to change the Genera reader, though, until
I hear from this list, in case my brain is just wedged. Can someone
either deconfuse or support me?
You raise some good points here. At first I was certain that the book
was not consistent, but now I have the following language lawyer's
argument:
The spec for APPEND says that all arguments but the last must be lists.
The comment about the last argument makes it clear that the others
are meant to be proper lists; see also the middle paragraph of page 27.
Therefore dotted lists are not allowed as values for D.
The examples on page 351 are also correct. Once you are given that
D may not be dotted, and given that the result of a backquoted
expression may or may not make copies, then the examples shown are
correct optimizations.
--Guy
∂29-Nov-88 1009 Common-Lisp-mailer Common Lisp for SUNS
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 29 Nov 88 10:09:03 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA01681g; Tue, 29 Nov 88 10:06:59 PST
Received: by bhopal id AA01309g; Tue, 29 Nov 88 10:05:50 PST
Date: Tue, 29 Nov 88 10:05:50 PST
From: Jim McDonald <jlm@lucid.com>
Message-Id: <8811291805.AA01309@bhopal>
To: bill@red.ipsa.dnd.ca
In-Reply-To: Bill Pase's message of Tue, 29 Nov 88 11:14:29 EST <8811291614.AA01479@red.ipsa.dnd.ca>
Subject: Common Lisp for SUNS
Cc: common-lisp@sail.stanford.edu
I'm not the right person to send you benchmark data on Lucid Common
Lisp, but I thought I should mention that Sun Common Lisp is Lucid
Common Lisp. (Lucid makes it, Sun sells it.)
Also, I can give some general advice about benchmarks:
(1) Be sure to note the releases being compared. For example, LCL
Version 3.0 is significantly different from LCL Version 2.1. We
added a second compiler, an ephemeral garbage collector,
multi-tasking, better inline floating point code, new interrupts,
new I/O, etc., etc.
(2) Be sure that the person who produced the benchmark values
understands the benchmarks and the lisp being tested. Proper use
of declarations and compiler settings can sometimes produce
order-of-magnitude differences. Also, for example, the use of a
feature such as ephemeral garbage collection may reflect a
decision to accept a somewhat increased running time in order to
avoid detectable pauses for GC. Turning EGC off may result in
different (usually faster) benchmark values, and might or might
not be appropriate for various applications. You need to
understand how you're going to use the lisp to know what settings
are appropriate.
(3) Ask for the *precise* techniques used to obtain the benchmarks,
including processor speed, memory size, load on the machine, etc.
I know that some of the people at Lucid have produced benchmark
figures using what we call the "low-mode" -- we run each
benchmark about 20 times or more, then use some statistics to
produce a number one could expect to be the low value obtained
in a typical set of about 3 runs. (We didn't want to just
scrounge for the lowest value, since that's not always
reproducible, yet did want to give a fair indication of the
performance possible.) I'm pretty sure the techniques used are
distributed with the benchmark numbers.
(4) If performance is critical, explain this to the vendor. For
example, Lucid is now productizing tools to reorganize your code
based on an analysis of its dynamic performance, since code and
data locality can have order-of-magnitude affects on real-life
applications. Remember that you are going to be running
applications day-to-day, and not just benchmarks. Support in
this area can be as crucial as the underlying speed of the lisp!
Happy hunting,
jlm
∂29-Nov-88 1035 Common-Lisp-mailer Re: inconsistency in backquote spec?
Received: from Xerox.COM by SAIL.Stanford.EDU with TCP; 29 Nov 88 10:35:37 PST
Received: from Burger.ms by ArpaGateway.ms ; 29 NOV 88 10:27:42 PST
Sender: "Larry_Masinter.PARC"@Xerox.COM
Date: 29 Nov 88 10:23:29 PST (Tuesday)
Subject: Re: inconsistency in backquote spec?
From: "Larry_Masinter.PARC"@Xerox.COM
To: Greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp@sail.stanford.EDU
In-Reply-to: Greenwald%STONY-BROOK.SCRC.Symbolics:COM:Xerox's message of 28
Nov 88 18:12
Message-ID: <881129-102742-5383@Xerox>
There are two relevant cleanup proposals, one of which passed, and the
other still pending. The first, called APPEND-DOTTED, clarifies the
behavior of APPEND given dotted lists. The second, which is really not firm
at all, is called BACKQUOTE-UNDERSPECIFIED, and it will attempt to specify
more precisely the behavior of backquote in terms of what parts of the
expansion get newly consed, etc.
Status: PASSED
Issue: APPEND-DOTTED
References: APPEND (p268)
Category: CHANGE/CLARIFICATION
Edit history: 27-Jul-87, Version 1 by Pitman
29-Oct-87, Version 2 by Pitman (loose ends)
14-Nov-87, Version 3 by Masinter
23-Nov-87, Version 4 by Masinter
14-Jan-88, Version 5 by Masinter
Problem Description:
The description of APPEND on p268 is not adequately clear on the issue of
what happens if an argument to APPEND is a dotted list. The only case
explicitly mentioned is the last argument, viz:
"The last argument [to APPEND] actually need not be a list but may be any
LISP object, which becomes the tail end of the constructed list. For
example, (append '(a b c) 'd) => (a b c . d)."
While this specifies the behavior of APPEND when the last argument is not a
list, the behavior when any of the other arguments are not lists is not
specified.
Proposal (APPEND-DOTTED:REPLACE):
Define that the cdr of the last cons in any but the last argument given to
APPEND or NCONC is discarded (whether NIL or not) when preparing the list
to be returned.
In the degenerate case where there is no last cons (i.e., the argument is
NIL) in any but the last list argument, clarify that the entire argument is
effectively ignored. Point out that in this situation, if the last argument
is a non-list, the result of APPEND or NCONC can be a non-list.
Remove any text which suggests that (APPEND x '()) and (COPY-LIST x) are
the same, since these two might legitimately differ in situations involving
dotted lists. As such, deciding which to use is not just a stylistic issue.
Examples:
(APPEND '(A B C . D) '()) => (A B C) ;Proposed
(NCONC (LIST* 'A 'B 'C 'D) '()) => (A B C) ;Proposed
Note that (COPY-LIST '(A B C . D)) would still return (A B C . D).
(APPEND '(A B . C) '() 3) => (A B . 3) ;Proposed
(NCONC (LIST* 'A 'B 'C) '() 3) => (A B . 3) ;Proposed
(APPEND '() 17) => 17 ;Proposed
(NCONC (LIST) 17) => 17 ;Proposed
Rationale:
This function is used a lot and its behavior should be well-defined across
implementations. This proposal upholds the apparent status quo in a number
of implementations.
Current Practice:
Symbolics Lisp, Vaxlisp, and Lucid Lisp appear to implement the proposed
interpretation (at least in the interpreter). Franz's Allegro Common Lisp
conforms to the proposed behavior except in the case of (NCONC (LIST) 17)
=> 17, where it returns NIL instead of 17.
Kyoto Common Lisp signal an error when using APPEND or NCONC on a dotted
list. Xerox Common Lisp signals an error on APPEND and implements the
proposed interpretation on NCONC.
Cost to implementors:
Technically, the change should be relatively small for those
implementations which don't already implement it. However, implementations
which have microcoded APPEND or NCONC incompatibly may find the small
change somewhat painful.
Some implementations may have optimized their APPEND or NCONC to expect
only NIL when SAFETY is 0. In this case, depending on implementation
details, requiring an ATOM check rather than a NULL check may slow things
down.
Cost to users:
This change is upward compatible.
Benefits:
Since non-lists are allowed as a last argument and since APPEND and NCONC
can therefore produce dotted lists, some readers may have (incorrectly)
assumed that APPEND and NCONC can reliably deal in general with dotted
lists, something that doesn't appear to be guaranteed by a strict reading.
The proposed extension would happen to legitimize such assumptions.
Aesthetics:
Whether or not users will think this improves the aesthetics of the
language will depend largely on how they view the relation between lists
and dotted lists. Those who view dotted lists as a special kind of list may
feel differently than those who view lists as a special kind of dotted
list.
Discussion:
The cleanup committee supports this proposal.
∂29-Nov-88 1050 Common-Lisp-mailer inconsistency in backquote spec?
Received: from STONY-BROOK.SCRC.Symbolics.COM (SCRC-STONY-BROOK.ARPA) by SAIL.Stanford.EDU with TCP; 29 Nov 88 10:50:46 PST
Received: from NOEL-COWARD.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via INTERNET with SMTP id 499350; 29 Nov 88 13:50:23 EST
Date: Tue, 29 Nov 88 13:55 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
To: jonl@lucid.com, Greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811290810.AA00624@bhopal>
Message-ID: <19881129185543.0.GREENWALD@NOEL-COWARD.SCRC.Symbolics.COM>
Date: Tue, 29 Nov 88 00:10:53 PST
From: Jon L White <jonl@lucid.com>
re: However, the example at the bottom of page 350 suggest alternate
"legitimate interpretations" continued on the top of pg 351. All of
them except the first, consider (APPEND .... D NIL) to be equivalent to
(APPEND ... D), which isn't true if D can be a dotted list.
[This may be a question about "standard lists" more than about backquote.]
I remember some sleeping dogs about APPEND -- all arguments except the last
are required to be "lists". Since APPEND has to copy the next to last
argument, it must cdr down to the last cell of the list; thus it should
complain about non-standard lists. [The permission to use non-standard
lists is primarily when the operation of interest will not cdr down to
the last cell, and hence it would be a moot question.]
Long long ago, Lucid made the decision to make non-standard lists acceptable
just about everwhere that "lists" are. Thus in Lucid Common Lisp:
(APPEND '(A . B) NIL) ==> (A)
(APPEND NIL '(A . B)) ==> (A . B)
I agree with this (I think there's a CL cleanup that specifies this
behavior for APPEND and NCONC), and therefore the Lucid backquote
implementation is inconsistent with the definition of APPEND.
(setq d '(a . b))
`(,@d)
`(,@d . nil)
(append [,@d] 'nil)
(append d 'nil)
(append '(a . b) 'nil)
should be (a), as in your example above.
However, it was (a . b) on the version I tried - I didn't try the APPEND
case itself, so maybe in a later version both were made consistent.
I can't say that I am fully happy with this; but it's very low on my
list of worries today.
-- JonL --
∂29-Nov-88 1127 Common-Lisp-mailer Re: Common Lisp for SUNS
Received: from tut.cis.ohio-state.edu by SAIL.Stanford.EDU with TCP; 29 Nov 88 11:27:05 PST
Received: by tut.cis.ohio-state.edu (5.59/2.881128)
id AA25824; Tue, 29 Nov 88 14:12:36 EST
Date: Tue, 29 Nov 88 14:12:36 EST
From: Arun Welch <welch@cis.ohio-state.edu>
Message-Id: <8811291912.AA25824@tut.cis.ohio-state.edu>
To: barmar@think.com
Cc: common-lisp@sail.stanford.edu
Subject: Re: Common Lisp for SUNS
>
>Kyoto CL is not generally considered a high-performance Lisp. Its major
>feature is its portability, since it is written mostly in C and its
>compiler uses C as the intermediate language. It is also well-known for
>being very faithful to CLtL, implementing all and only what the book
>says.
We're in the process of coming up with a decision on what lisp to get
for the University, and have been looking at Ibuki, Franz, and Envos
(and, as soon as Sun sends us the tape, Sun/ Lucid). Part of this has
been benchmarking them on Sun-3's and Sun-4's, and we've noticed that
in some benchmarks on the -4 Ibuki comes out ahead of the others. We were kind
of amazed by this, until we realised that Ibuki uses the native C
compiler, which is optimising for the SPARC architecture on the -4,
while none of the others were. This wasn't an across-the-board
speedup, just for some of the things we tried. I'd pretty much agree
with your other assessment of Kyoto CL, modulo the fact that Ibuki has
extended it somewhat (folding in the new error system, for example).
...arun
----------------------------------------------------------------------------
Arun Welch
Lisp Systems Programmer, Lab for AI Research, Ohio State University
welch@tut.cis.ohio-state.edu
∂29-Nov-88 1138 Common-Lisp-mailer inconsistency in backquote spec?
Received: from SAPSUCKER.SCRC.Symbolics.COM ([128.81.41.223]) by SAIL.Stanford.EDU with TCP; 29 Nov 88 11:36:04 PST
Received: from NOEL-COWARD.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via INTERNET with SMTP id 262367; 29 Nov 88 14:02:36 EST
Date: Tue, 29 Nov 88 14:05 EST
From: Michael Greenwald <Greenwald@STONY-BROOK.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
To: gls@Think.COM, Greenwald@STONY-BROOK.SCRC.Symbolics.COM
cc: common-lisp@sail.stanford.edu
In-Reply-To: <8811291735.AA00711@joplin.think.com>
Message-ID: <19881129190543.1.GREENWALD@NOEL-COWARD.SCRC.Symbolics.COM>
Date: Tue, 29 Nov 88 12:35:36 EST
From: gls@Think.COM
Date: Mon, 28 Nov 88 20:44 EST
From: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
(setq d '(a . b))
'`(,@d) => `(a . b) or `(a)?
If you read CLtL, pg 350. it says that it's equivalent to
`(,@d . nil)
which is
(append [,@d] 'nil)
(append d 'nil)
which suggests the correct value is `(a).
...
Are dotted lists not allowed as values of D? Is the spec on pg 350
correct, and the examples on pg. 351 incorrect?
I tend to believe the latter. In which case, all of the readers I tried
are incorrect. I'm not going to change the Genera reader, though, until
I hear from this list, in case my brain is just wedged. Can someone
either deconfuse or support me?
You raise some good points here. At first I was certain that the book
was not consistent, but now I have the following language lawyer's
argument:
The spec for APPEND says that all arguments but the last must be lists.
The comment about the last argument makes it clear that the others
are meant to be proper lists; see also the middle paragraph of page 27.
Therefore dotted lists are not allowed as values for D.
I thought a (recent?) CL Cleanup specified that if arguments (all but
the last) to APPEND (or NCONC) were dotted lists, the non-nil final CDR
was to be ignored. In which case, the examples on 351 are incorrect.
Or, you could say that the list following a ,@ cannot be dotted.
Either way, I think, requires a minor clarification in the CL spec.
The examples on page 351 are also correct. Once you are given that
D may not be dotted, and given that the result of a backquoted
expression may or may not make copies, then the examples shown are
correct optimizations.
--Guy
∂29-Nov-88 1353 Common-Lisp-mailer Re: Common Lisp for SUNS
Received: from ucbarpa.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 29 Nov 88 13:53:02 PST
Received: by ucbarpa.Berkeley.EDU (5.61/1.29)
id AA24518; Tue, 29 Nov 88 13:52:04 PST
Received: from frisky by franz (3.2/3.14)
id AA24713; Tue, 29 Nov 88 13:43:03 PST
Received: by frisky (3.2/3.14)
id AA02600; Tue, 29 Nov 88 13:40:54 PST
From: franz!frisky!jkf@ucbarpa.Berkeley.EDU (John Foderaro)
Return-Path: <frisky!jkf>
Message-Id: <8811292140.AA02600@frisky>
To: franz!ucbarpa!red.ipsa.dnd.ca!bill (Bill Pase)
Cc: franz!sail.stanford.edu!common-lisp
Subject: Re: Common Lisp for SUNS
In-Reply-To: Your message of Tue, 29 Nov 88 11:14:29 EST.
<8811291614.AA01479@red.ipsa.dnd.ca>
Date: Tue, 29 Nov 88 13:40:53 PST
Regarding benchmarking Lisps.
1. Declarations are important for speed, but you'll find that some
Lisps will require more specific declarations than others.
For example Sun's Lisp only supports one floating point type so declaring
something to be a 'float' is sufficient for the compiler to open code
the operation. Allegro supports two types of floats so you must declare
either 'single-float' or 'double-float.'
2. Different systems do different amounts of optimizations based on
the settings of the optimization parameters speed, safety and size.
Probably the only comparable values are for speed=3, safety=0, size=0
where each system does maximum optimization. While benchmarks
run at this value are interesting you probably aren't going to
do development with these settings since you aren't going to get
good diagnostics.
Regarding the Lisp on the Sun4.
Allegro is highly optimized for the Sun4 but you have to
add some declarations and specify that speed is important.
The comment was made that a C based Lisp on the Sun4 would
be very fast because of sun's optimizing C compiler.
While it is true that by using C you can take advantage of that
compiler, it is also true that the use of C constrains your
whole system design so you can't use the machine optimally.
I say this from many years experience programming in C parts of the
kernel of Franz Lisp. To cite two examples for the Sun4:
One of the nicest features of the sun4 (sparc) architecture
is the support the the Lisp fixnum data type (there are 'tagged'
versions of the add, subtract and compare instructions).
This allows the compiler to open code +,-,<,<=.. and so on
and if the operands happen to be fixnums (they very often are)
then the operation and fixnum tag check can go on in parallel.
This makes for fast computation in the typical case
and it is completely safe (if the tags aren't fixnum you find out
about it and perform the appropriate operation for the
actual data types).
A C based lisp can't make use of these tagged instructions.
The Sun4 has 7 global registers. Allegro stores nil and a
pointer to our global function table in one of them, and
uses another for tracking asychronous interrupts. Another
is used to pass argument/result counts. C doesn't permit
global register declarations so you can't take advantage
of this nice feature of the Sun4 in a C-based Lisp.
[The use of machine registers to hold certain values was
so important in Franz Lisp that for certain regular
architectures (e.g. vax) an incredible hack was written
by Keith Sklower to modify the assembler language coming
out of the C compiler to change certain memory references
to register references and to fix the register save masks.]
-- John Foderaro
Franz Inc.
jkf%franz.uucp@berkeley.edu
∂29-Nov-88 1430 Common-Lisp-mailer inconsistency in backquote spec?
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 29 Nov 88 14:26:57 PST
Received: from fafnir.think.com by Think.COM; Tue, 29 Nov 88 17:12:08 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Tue, 29 Nov 88 17:12:45 EST
Received: from joplin.think.com by verdi.think.com; Tue, 29 Nov 88 17:11:14 EST
Received: by joplin.think.com; Tue, 29 Nov 88 17:12:40 EST
Date: Tue, 29 Nov 88 17:12:40 EST
From: gls@Think.COM
Message-Id: <8811292212.AA00825@joplin.think.com>
To: Greenwald@stony-brook.scrc.symbolics.com
Cc: gls@Think.COM, Greenwald@stony-brook.scrc.symbolics.com,
common-lisp@sail.stanford.edu
In-Reply-To: Michael Greenwald's message of Tue, 29 Nov 88 14:05 EST <19881129190543.1.GREENWALD@NOEL-COWARD.SCRC.Symbolics.COM>
Subject: inconsistency in backquote spec?
Date: Tue, 29 Nov 88 14:05 EST
From: Michael Greenwald <Greenwald@stony-brook.scrc.symbolics.com>
Date: Tue, 29 Nov 88 12:35:36 EST
From: gls@Think.COM
...
You raise some good points here. At first I was certain that the book
was not consistent, but now I have the following language lawyer's
argument:
The spec for APPEND says that all arguments but the last must be lists.
The comment about the last argument makes it clear that the others
are meant to be proper lists; see also the middle paragraph of page 27.
Therefore dotted lists are not allowed as values for D.
I thought a (recent?) CL Cleanup specified that if arguments (all but
the last) to APPEND (or NCONC) were dotted lists, the non-nil final CDR
was to be ignored. In which case, the examples on 351 are incorrect.
Because you sent the mail out to common-lisp@sail and not to
any of the X3J13 mailing lists, I assumed that you were asking
a question about the language as defined solely by the book.
In other words, I assume that the audience for the common-lisp
mailing list has not necessarily followed all of the X3J13 work.
It is true that eventual adoption of this cleanup item would
invalidate the examples.
--Guy
∂29-Nov-88 2057 Common-Lisp-mailer Common Lisp for SUNS
Received: from argus.Stanford.EDU by SAIL.Stanford.EDU with TCP; 29 Nov 88 20:57:39 PST
Received: from Riverside.SCRC.Symbolics.COM (SCRC-RIVERSIDE.ARPA) by argus.Stanford.EDU with TCP; Tue, 29 Nov 88 20:50:28 PST
Received: from F.ILA.Dialnet.Symbolics.COM (FUJI.ILA.DIALNET.SYMBOLICS.COM) by Riverside.SCRC.Symbolics.COM via DIAL with SMTP id 297298; 29 Nov 88 23:56:09 EST
Date: Tue, 29 Nov 88 23:42 EST
From: Robert W. Kerns <RWK@f.ila.dialnet.symbolics.com>
Subject: Common Lisp for SUNS
To: Bill Pase <bill@red.ipsa.dnd.ca>, common-lisp@sail.stanford.edu
In-Reply-To: <8811291614.AA01479@red.ipsa.dnd.ca>
Message-Id: <19881130044245.2.RWK@F.ILA.Dialnet.Symbolics.COM>
Date: Tue, 29 Nov 88 11:14:29 EST
From: bill@red.ipsa.dnd.ca (Bill Pase)
I'm especially interested in the run time performance, since we hope
to use one of these lisps as a delivery vehicle for code developed on
Symbolics Computers. (It'd be real nice if the lisp benchmark data
was available?) Of course if anyone has experiences with using these
systems as a development environment, I'd not mind hearing it.
/bill
I have only subjective things to give you, but you will be astonished at the
performance difference between KCL and any Symbolics machine. I've only done
close-in comparisons with a Symbolics system with minimum memory, running on a
large Sun-3. For realistic size problems (like compilation, for instance),
KCL is pretty slow. Well, compilation isn't really a fair choice since it has
to get compiled twice; once in Lisp and once in C.
It is also pretty weak in the development arena. I would choose either of the
other two alternatives you list. The major feature of KCL is that it is
nearly free, but remember, Time is Money, too.
There is also a third choice: Ibuki Common Lisp, which is an improved version
of KCL. It is supposedly much more usable for development, with a lot of work
done on the debugger, etc. I don't know anything about its performance. I
don't know its price, but I suspect it's less than the other two.
There's also a fourth choice, another version of KCL, which I don't know much
about.
∂30-Nov-88 1856 Common-Lisp-mailer commonlisp types
Received: from vaxa.isi.edu by SAIL.Stanford.EDU with TCP; 30 Nov 88 18:56:05 PST
Posted-Date: Wed, 30 Nov 88 18:55:38 PST
Message-Id: <8812010255.AA17146@vaxa.isi.edu>
Received: from LOCALHOST by vaxa.isi.edu (5.59/5.51)
id AA17146; Wed, 30 Nov 88 18:55:41 PST
To: common-lisp@sail.stanford.edu
Subject: commonlisp types
Date: Wed, 30 Nov 88 18:55:38 PST
From: Don Cohen <donc@vaxa.isi.edu>
There seems to be nothing in CLtL that answers the question:
"is x a legal type specifier?"
The description of TypeP says that the type argument may be
any of the legal type specifiers except (function ...) or
(values ...).
I would hope that would mean that for any such "legal
arguments" typep would not cause an error. I would also
hope that any illegal type would cause an error.
On the other hand the description of how typep handles
(satisfies ...) indicates that errors might well result.
Intuitively, it seems to me that if an error results from
that test the typep test ought to return nil, e.g.,
(typep nil '(satisfies zerop))
I'd like the spec to say that typep first decides whether
the type is legal, and signals an error if not. Then,
for things like satisfies, it applies the predicate but
catches errors, and returns nil if an error occurs.
What do you experts (and lawyers) out there think?
∂01-Dec-88 0807 Common-Lisp-mailer commonlisp types
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 1 Dec 88 08:06:41 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Thu, 1 Dec 88 10:48:06 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Thu, 1 Dec 88 11:04:43 EST
Date: Thu, 1 Dec 88 11:04 EST
From: Barry Margolin <barmar@Think.COM>
Subject: commonlisp types
To: Don Cohen <donc@vaxa.isi.edu>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8812010255.AA17146@vaxa.isi.edu>
Message-Id: <19881201160446.1.BARMAR@OCCAM.THINK.COM>
Date: Wed, 30 Nov 88 18:55:38 PST
From: Don Cohen <donc@vaxa.isi.edu>
There seems to be nothing in CLtL that answers the question:
"is x a legal type specifier?"
The description of TypeP says that the type argument may be
any of the legal type specifiers except (function ...) or
(values ...).
I would hope that would mean that for any such "legal
arguments" typep would not cause an error. I would also
hope that any illegal type would cause an error.
On the other hand the description of how typep handles
(satisfies ...) indicates that errors might well result.
Intuitively, it seems to me that if an error results from
that test the typep test ought to return nil, e.g.,
(typep nil '(satisfies zerop))
I'd like the spec to say that typep first decides whether
the type is legal, and signals an error if not. Then,
for things like satisfies, it applies the predicate but
catches errors, and returns nil if an error occurs.
What do you experts (and lawyers) out there think?
Since CLtL doesn't say that TYPEP must signal an error if the type
specifier is invalid, it currently "is an error" if the type specifier
is not a valid type specifer other than (FUNCTION ...) or (VALUES ...).
I don't think there has been any suggestion within X3J13 to change this.
In general, Common Lisp tends not to require implementations to do lots
of this kind of checking; at high safety optimization levels it is
informally encouraged, but not required.
Actually, in this particular case, I don't think that requiring an error
to be signalled would be too bad. TYPEP must already do a significant
amount of work to decode the type specifier, so it probably knows when
the type specifier is invalid, and signalling an error would be pretty
easy. However, putting this requirement into the CL standard would be
an incompatible change to the language definition, with only minor gain,
and I think it is kind of late for it now (we're not very far from
trying to get a draft finished).
As for your suggestion about (SATISFIES ...), I personally think that is
a bad idea. TYPEP shouldn't silently hide bugs in the programmer's
predicate. The above example should have been written as
(typep nil '(and number (satisfies zerop)))
barmar
∂01-Dec-88 2205 Common-Lisp-mailer Re: commonlisp types
Received: from SPICE.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 1 Dec 88 22:04:56 PST
Date: Fri, 2 Dec 1988 00:40-EST
From: Jamie.Zawinski <jwz@spice.cs.cmu.edu>
To: common-lisp@sail.stanford.edu
Subject: Re: commonlisp types
...but I believe it is the case that there is no CL way to determine
if a given type is defined.
I wish there was some CL way to define a complex type and insert it in
the existing hierarchy. For example, I once tried to define the type
LIST-OF, which would be used like
(TYPEP '(1 2 3) '(LIST-OF FIXNUM)) ==> T
(TYPEP '(A B 3) '(LIST-OF FIXNUM)) ==> NIL
(SUBTYPEP '(LIST-OF SYMBOL) 'LIST) ==> T
(SUBTYPEP '(LIST-OF FIXNUM) '(LIST-OF NUMBER)) ==> T
(SUBTYPEP '(LIST-OF *) '(LIST-OF LIST)) ==> NIL NIL
On the TI Explorer this was really easy.
In Lucid CL, it was not possible except by bashing the definitions of
TYPEP and SUBTYPEP.
Can someone explain the rationale behind forcing SATISFIES to
accept only function-names and not lambda expressions?
I can see that the compiler could have special knowledge about
such forms as (SATISFIES PLUSP), but CLtL says lambdas are excluded
"to avoid scoping problems."
Jamie
∂02-Dec-88 0804 Common-Lisp-mailer Re: commonlisp types
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 2 Dec 88 08:04:04 PST
Return-Path: <barmar@Think.COM>
Received: from sauron.think.com by Think.COM; Fri, 2 Dec 88 10:41:22 EST
Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 2 Dec 88 11:02:22 EST
Date: Fri, 2 Dec 88 11:02 EST
From: Barry Margolin <barmar@Think.COM>
Subject: Re: commonlisp types
To: Jamie.Zawinski <jwz@spice.cs.cmu.edu>
Cc: common-lisp@sail.stanford.edu
In-Reply-To: <8812020545.AA12869@Think.COM>
Message-Id: <19881202160232.8.BARMAR@OCCAM.THINK.COM>
Date: Fri, 2 Dec 1988 00:40-EST
From: Jamie.Zawinski <jwz@spice.cs.cmu.edu>
Can someone explain the rationale behind forcing SATISFIES to
accept only function-names and not lambda expressions?
I can see that the compiler could have special knowledge about
such forms as (SATISFIES PLUSP), but CLtL says lambdas are excluded
"to avoid scoping problems."
I think this means that they didn't want to create confusion about
whether the lambda expressions produced lexical closures or not.
Someone might think that the following would work:
(defun strange-eq (x y)
(typep x '(satisfies (lambda (object) (eq object y)))))
barmar
∂02-Dec-88 0810 Common-Lisp-mailer Re: Common Lisp for SUNS
Received: from labrea.stanford.edu by SAIL.Stanford.EDU with TCP; 2 Dec 88 08:10:16 PST
Received: by labrea.stanford.edu; Fri, 2 Dec 88 08:09:07 PST
Received: by ibuki.UUCP (5.52/4.7)
id AA12633; Thu, 1 Dec 88 15:50:57 PST
Date: Thu, 1 Dec 88 15:50:57 PST
From: ibuki!dbp@labrea.stanford.edu (David Posner)
Message-Id: <8812012350.AA12633@ibuki.UUCP>
To: common-lisp@sail.stanford.edu
Subject: Re: Common Lisp for SUNS
Some comments on John Foderaro's comments on "C-based" Lisps
This is in response John Foderaro's comments on "C based" Lisps on the
Sun 4. (IBUKI Common Lisp, a derivative of Kyoto Common Lisp, is such
a "C based" lisp.) First, a general remark, comparisons with Franz Lisp
are simply not valid. Professors Yuasa and Hagiya, the original designers
of KCL, had the benefit of 3 decades of work on Lisp implementation and
compiler development (including Franz Lisp and all the more recent work
on compiler technology) on which to base their work. They knew all of
this technology. In addition they are first class computer scientists
and awesome hackers. They were extremely concerned with performance
and they built a system which competes quite favorably with "direct"
implementations. (John should consider not what he did those many years
ago but rather what he would be capable of doing today.)
With respect to John's specific comments.
1) The use of global registers on the Sun 4.
"The Sun4 has 7 global registers. Allegro stores nil and a
pointer to our global function table in one of them, and
uses another for tracking asynchronous interrupts. Another
is used to pass argument/result counts. C doesn't permit
global register declarations so you can't take advantage
of this nice feature of the Sun4 in a C-based Lisp."
Allegro seem to have 4 uses for the global registers:
(a) pointing to a "global function table";
(b) asynchronous interrupt "tracking";
(c) nil testing.
(d) multiple value handling;
(a) is not necessary. I assume that the "global function table" is a transfer
vector used to call Allegro kernel functions. In IBCL and KCL calls to
kernel functions are directly linked and so there is no need to call indirect
through a transfer vector. (This is in fact an implicit win for the C based
Lisps.)
(b) is of marginal value. As I recall, The Allegro compiler inserts code
to poll for interrupts in which case the register is obviously of value. The
only interrupt polling in IBCL however occurs when entering critical sections.
(c) is of marginal value. Not having nil in a register costs at most a couple
of cycles in doing a nil test (2 immediate instructions to build the constant.)
The only case in which this could possibly be significant is in an extremely
tight loop but in that case the IBCL back-end optimizer (the C-compiler!) can
simply reserve a register for nil and store nil once on loop entry.
(d) is hard to assess because I do not know much about how Allegro handles
multiple values and lambda list parsing. Conceivably this could amount to
a few percent in function call intensive code. The next release of IBCL will
include considerable performance enhancements for function calling. (One of
the beauties of the original work at Kyoto is the modularity and extensibility
of the implementation -- in particular the compiler.)
In short I strongly doubt that Allegro's use of global registers gives it
anything more than a marginal advantage over the C based Lisps.
(2) The ability to exploit tagged arithmetic. IBCL and KCL do not currently
do any open coding of generic arithmetic. This loses when generic
operators are used to do fixnum arithmetic. IBCL will be making considerable
improvements in this area in its next release but even so in most cases the
right thing to do is to use fixnum operators to do fixnum arithmetic, and
floating point operators to do floating point arithmetic, i.e., add
appropriate type declarations to the code. When declarations are in place
IBCL and KCL compile Lisp arithmetic to equivalent C arithmetic and from
that point it is doubtful that the Allegro compiler will do better than the
optimizing C-compiler.
I would like to add an Amen to Jim McDonald's points about benchmarking
and interpretation of benchmarks. [I saw an ad recently touting one lisp
as running "23% faster" than another on the Gabriels (except it didn't call
them that) without any explanation of how the benchmarks were made and
how they summarized the results.] Advertized benchmarks are typically
run on stand alone maxed out hardware. On real systems the small size
of the C based Lisps (the total image size is about 2 megs
including compiler) is likely to be just as important as how registers
get used.
Another area where "C-based" lisps win is in the ability to tightly integrate
with "foreign" code. IBCL and KCL use the systems object format and their
Lisp data structures are also C data structures. The term "foreign" in this
case is essentially a misnomer.
Another issue that benchmarking doesn't account for is the lead time
between the availability of hardware and the availability of a Lisp.
For the six months or so when IBCL was the only lisp available
on the Sun 4 it might have been reasonable to compare IBCL on a Sun 4
with other Lisps on a Sun 3. This is the current situation on HP
Spectrum series and the MIPS based platforms (e.g., the Silicon Graphics
4D). This will undoubtedly be the situation for the new Apollo and
Motorola based RISCs in the future. In each case the companies
producing direct implementations are going to be in the business of
trying to duplicate all of the back end complexity of the manufacturer's
compilers. With the new architectures the complexity entailed in doing
decent instruction scheduling and register allocation and exploiting
low level parallelism is enormous. I doubt that this duplication
of effort will prove to be cost effective for most applications.
Dave Posner
IBUKI
ibuki!dbp@labrea.stanford.edu
∂02-Dec-88 0836 Common-Lisp-mailer commonlisp types
Received: from Think.COM by SAIL.Stanford.EDU with TCP; 2 Dec 88 08:36:41 PST
Received: from fafnir.think.com by Think.COM; Fri, 2 Dec 88 11:13:42 EST
Return-Path: <gls@Think.COM>
Received: from verdi.think.com by fafnir.think.com; Fri, 2 Dec 88 11:34:51 EST
Received: by verdi.think.com; Fri, 2 Dec 88 11:33:22 EST
Date: Fri, 2 Dec 88 11:33:22 EST
From: Guy Steele <gls@Think.COM>
Message-Id: <8812021633.AA05964@verdi.think.com>
To: jwz@spice.cs.cmu.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Jamie.Zawinski's message of Fri, 2 Dec 1988 00:40-EST <8812020545.AA12869@Think.COM>
Subject: commonlisp types
Date: Fri, 2 Dec 1988 00:40-EST
From: Jamie.Zawinski <jwz@spice.cs.cmu.edu>
...
Can someone explain the rationale behind forcing SATISFIES to
accept only function-names and not lambda expressions?
I can see that the compiler could have special knowledge about
such forms as (SATISFIES PLUSP), but CLtL says lambdas are excluded
"to avoid scoping problems."
Consider
(defun bazola (linguini pop-tarts)
(declare (type (satisfies (lambda (x) (< x linguini))) pop-tarts))
...)
I'm trying to say that pop-tarts is always smaller in value than linguini.
The lambda expression appears lexically within the binding of linguini,
so one might expect that the free reference to linguini is legitimate.
But it can't work.
Similarly this cannot work:
(defun bazola (linguini pop-tarts)
(assert (typep pop-tarts '(satisfies (lambda (x) (< x linguini)))))
...)
[Of course, this can be rendered instead as
(defun bazola (linguini pop-tarts)
(assert (< pop-tarts linguini))
...)
but that is beside the point.]
One might conceivably argue that SATISFIES should allow an actual
function and not just a name; then one might try
(defun bazola (linguini pop-tarts)
(assert (typep pop-tarts `(satisfies ,(lambda (x) (< x linguini)))))
...)
but this approach doesn't help the declaration case. It's a basic problem
of compile-time versus run-time execution.
--Guy
∂04-Dec-88 2318 Common-Lisp-mailer Re: Common Lisp for SUNS
Received: from ucbarpa.Berkeley.EDU by SAIL.Stanford.EDU with TCP; 4 Dec 88 23:18:46 PST
Received: by ucbarpa.Berkeley.EDU (5.61/1.29)
id AA17362; Sun, 4 Dec 88 23:17:50 PST
Received: from frisky by franz (3.2/3.14)
id AA10238; Sun, 4 Dec 88 22:55:12 PST
Received: by frisky (3.2/3.14)
id AA14271; Sun, 4 Dec 88 22:52:47 PST
From: franz!frisky!jkf@ucbarpa.Berkeley.EDU (John Foderaro)
Return-Path: <frisky!jkf>
Message-Id: <8812050652.AA14271@frisky>
To: franz!ucbarpa!labrea.stanford.edu!ibuki!dbp (David Posner)
Cc: franz!sail.stanford.edu!common-lisp
Subject: Re: Common Lisp for SUNS
In-Reply-To: Your message of Thu, 01 Dec 88 15:50:57 PST.
<8812012350.AA12633@ibuki.UUCP>
Date: Sun, 04 Dec 88 22:52:46 PST
I'm sorry if you got the impression that I was criticizing the authors
of KCL. I'm sure that they are excellent programmers and have
developed the best possible C-based Lisp system.
What I do still question is the use of C as the intermediate language for a
Lisp compiler. I would like the put this question to Professors Yuasa
and Hagiya, "If your job was to write the *best possible* Lisp system
for a given machine, and you were allowed a reasonable amount of time
to do so, would you choose C as the intermediate language or would you
go directly to the machine language?" My answer would be of course to
go to machine language and I suspect that they would agree. However, if the
goal is to write a Lisp that is a portable as possible and where
efficiency is important only as long as it doesn't get in the way of
portability, then using C may be a good idea.
C was a good match for the PDP-11 but on every machine since then it
has been a compromise, with the nice new features of the each
architecture frequently being inaccessible to the C programmer
(e.g. the tagged add's and the global registers of the sun4). If your
goal is the *best possible* Lisp then you should use all the
features of the architecture that are appropriate for Lisp. [Your
conclusion on the uselessness of global registers in the sun4
only looked at the first-order effects. Yes, you don't need a global
pointer if you use direct linked calls, however the use of
a global pointer gives one position independent code which permits the system
to have a copying garbage collector (without maintaining relocation tables)
which has important benefits in paging and so on and so on]
You said that your compiler does well when everything is declared and
speed=3 and safety=0. This situation occurs in less than 1% of the code
I write. I believe that Lisp has to work well in the mode where
the user just wants the speedup the compiler provides and doesn't
want to lose the interactive detection of errors he would get from
running the code interpreted. If the Lisp does a good enough job at
inlining type checks the user will be satisfied with the performance
and won't even crank up the speed and lower the safety. Inline
type checking is a case where there are clever hacks (unexpressible in C)
than implementor can use.
Yes, it does take time to port Lisp to a machine if you have to
study the architecture in detail and write in machine code.
However, computer manufacturers are convinced that Lisp is an important
language to offer so typically they supply machines to Lisp implementation
companies well before the the machines are introduced to the public.
Thus a C-based implementation won't 'get to market' that much
earlier (if any earlier). As for architectures that existed before
Common Lisp 'took off', there are still a few important ones
without 'native' Lisp ports but that number is shrinking and will be
close to zero in six months to a year.
I don't mean to put down anyone or any company. Thinking back I realize
that I've spent a third of my life implementing Lisp on stock
hardware machines, so I guess that I've developed some strong opinions during
that time. Sorry for being so longwinded.
John Foderaro
Franz Inc.
∂05-Dec-88 1836 Common-Lisp-mailer CLtL for HP9000?
Received: from gateway.mitre.org by SAIL.Stanford.EDU with TCP; 5 Dec 88 18:36:26 PST
Received: by gateway.mitre.org (5.54/SMI-2.2)
id AA06609; Mon, 5 Dec 88 21:33:10 EST
Return-Path: <howell%community-chest.mitre.org@gateway.mitre.org>
Received: from localhost.mitre.org by community-chest.mitre.org (3.2/SMI-2.2)
id AA07696; Mon, 5 Dec 88 21:31:26 EST
Message-Id: <8812060231.AA07696@community-chest.mitre.org>
To: common-lisp@sail.stanford.edu, ailist@ai.ai.mit.edu
Subject: CLtL for HP9000?
Date: Mon, 05 Dec 88 21:31:25 -0500
From: howell%community-chest.mitre.org@gateway.mitre.org
Are there implementations of Common Lisp available for the HP 9000
(models 330/350/370, if it matters) under UNIX?
How about X-Windows, and CLX/CLUE for the same configuration?
Thanks for your help,
Chuck Howell
The MITRE Corporation, Mail Stop W418
7525 Colshire Drive, McLean, VA 22102
NET: howell@mitre.arpa or
howell%community-chest.mitre.org@gateway.mitre.org
∂06-Dec-88 2147 Common-Lisp-mailer commonlisp types
Received: from lucid.com by SAIL.Stanford.EDU with TCP; 6 Dec 88 21:46:59 PST
Received: from bhopal ([192.9.200.13]) by heavens-gate.lucid.com id AA00869g; Tue, 6 Dec 88 21:44:34 PST
Received: by bhopal id AA11501g; Tue, 6 Dec 88 21:46:27 PST
Date: Tue, 6 Dec 88 21:46:27 PST
From: Jon L White <jonl@lucid.com>
Message-Id: <8812070546.AA11501@bhopal>
To: donc@vaxa.isi.edu
Cc: common-lisp@sail.stanford.edu
In-Reply-To: Don Cohen's message of Wed, 30 Nov 88 18:55:38 PST <8812010255.AA17146@vaxa.isi.edu>
Subject: commonlisp types
re: There seems to be nothing in CLtL that answers the question:
"is x a legal type specifier?"
At the meeting that founded the X3J13 committee (on 6-Dec-85), Guy Steele
circulated a list of "non-controversial issues" and "Clarifications"
which included the following addition [typos faithfully reproduced]:
"(*) 51 Add a newefunction TYPE-SPECIFIER-P that is true of valid type
specifiers and fals of all other Lisp objects. Note that the use of
DEFSTRUCT and DEFTYPE can change the behavior of TYPE-SPECIFIER-P over
time."
Sad to say, this and many other "non-controversial" items included in
Guy's list of "Clarifications", has never been brought up in the X3J13
"Cleanup" subcommittee. However, Lucid's 3.0 release includes such
a function.
-- JonL --
∂07-Dec-88 0740 Common-Lisp-mailer #+ and *read-supress*
Received: from CENTRO.SOAR.CS.CMU.EDU by SAIL.Stanford.EDU with TCP; 7 Dec 88 07:39:44 PST
Received: from CENTRO.SOAR.CS.CMU.EDU by CENTRO.SOAR.CS.CMU.EDU; 7 Dec 88 00:15:23 EST
To: Common-Lisp@SAIL.STANFORD.EDU
cc: soar-archive@CENTRO.SOAR.CS.CMU.EDU
Subject: #+ and *read-supress*
Date: Wed, 07 Dec 88 00:14:22 EST
Message-ID: <22302.597474862@CENTRO.SOAR.CS.CMU.EDU>
From: Brian.Milnes@CENTRO.SOAR.CS.CMU.EDU
The Soar project is considering adopting "," as part of our
language's syntax. This is a dangerous move at best in a Common Lisp
implementation, but it would be quite nice for our purposes.
While the new version of Soar is under development, this read table
modification to comma is on a *feature*, :DSM. When I try and run my
test code over the old style code (i.e. #-:DSM),"#+:DSM form",
where form contains a comma, form will not read.
Page 359 says that *read-supress* is lambda bound non-nil during my
#+:DSM read of form when :DSM is not a member of *features*. Pages
345 and 346 of Steele's CLtL document *read-supress* and page 346
says,
"Note that, no matter what the value of *read-supress*, parentheses
still continue to delimit (and construct) lists; the #( construction
continues to delimit vectors; and comments, strings and the quote and
backquote constructions continue to be interpreted properly.
Furthermore, such situations as '), #<, #) and
#<space> continue to signal errors."
It is clear to me that we need parentheses, #(, comments and strings
to read correctly so that #+/- can delimit form. It also seems nice
to me that the usual reader errors will occur, such as '), #< and #).
What I'm missing is the rationale for having quote and backquote (and
its "," macro) still in operation. It would be nicer in this case if
commas were read over. Perhaps a rationale note should be added by the
clean up committee, or the quote and/or backquote should be removed from
*read-supress*.
Thanks, Brian Milnes (Milnes@centro.soar.cs.cmu.edu)